首页 > 其他分享 >(已改正)第十四届蓝桥B组省赛回忆版 E: 接龙数列

(已改正)第十四届蓝桥B组省赛回忆版 E: 接龙数列

时间:2023-04-09 18:34:17浏览次数:50  
标签:数字 数列 int 蓝桥 接龙 71 include 组省赛

目录

E: 接龙数列

原题

时间限制: 1s 内存限制: 256MB

题目描述

对于一个长度为 K 的整数数列:A1, A2, . . . , AK,我们称之为接龙数列当且仅当 Ai 的首位数字恰好等于 Ai−1 的末位数字 (2 ≤ i ≤ K)。
例如 12, 23, 35, 56, 61, 11 是接龙数列;12, 23, 34, 56 不是接龙数列,因为 56的首位数字不等于 34 的末位数字。所有长度为 1 的整数数列都是接龙数列。
现在给定一个长度为 N 的数列 A1, A2, . . . , AN,请你计算最少从中删除多少个数,可以使剩下的序列是接龙序列?

输入格式

第一行包含一个整数 N。
第二行包含 N 个整数 A1, A2, . . . , AN。

输出格式

一个整数代表答案。

样例输入

5
11 121 22 12 2023

样例输出

1

提示
删除 22,剩余 11, 121, 12, 2023 是接龙数列。

对于 20% 的数据,1 ≤ N ≤ 20。
对于 50% 的数据,1 ≤ N ≤ 10000。
对于 100% 的数据,1 ≤ N ≤ 105,1 ≤ Ai ≤ 109。所有 Ai 保证不包含前导 0。

错误版

思路: 求最长不连续的接龙数列的长度L, 输出 n - L

  1. 求当前数的前导数字上次出现的地方, 并更新f[]
  2. 更新当前数字的后导数字x对应的 pre[x]
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 1e5+10;
int f[N];
int pre[10]; // 数字上一次出现的位置
string v[N];

int main()
{
    int n;
    cin >> n;
    for(int i = 1; i <= n; ++i) {
        cin >> v[i];
        f[i] = 1;
    }

    int res = 0;
    pre[v[1][v[1].size()-1] - '0'] = 1;
    for(int i = 2; i <= n; ++i){
        int h = v[i][0] - '0', t = v[i][v[i].size()-1] - '0';
        f[i] = max(f[i], f[pre[h]]+1);
        res = max(res, f[i]);

        pre[t] = i;
    }
    cout << n-res;
    return 0;
}

改正版

经朋友指正, 我意识到这不是最优解

那上面哪里有问题呢? 可以举个例子

5
12 21 71 123 345

按上面的写法,输出2,

因为当71出现后, pre[1]更新为3 (即上一次以1结尾的数的位置更新为71的下标)

按此思路最终最长的接龙数列是"71 123 345", 并不是全局最优解, 71的出现让后面的数忘记了在71之前以1结尾的其他数, 因此陷入了局部最优解

改进后新增了一个preLen[], preLen[i]表示当前以数字i结尾的接龙数组的最大长度

这样在上面的71出现时, 因为"12 21"的接龙长度大于"71"的接龙长度, 所以不更新pre[], 仿佛71从未来过一般; 否则就更新.

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 1e5+10;
int f[N];		//f[i]: 以第i个字符串结尾的接龙数列的长度
int pre[10]; 	//数字上一次出现的位置
int preLen[10]; //preLen[i]:当前以数字i结尾的接龙最大长度
string v[N];

int main()
{
    int n;
    cin >> n;
    for(int i = 1; i <= n; ++i) {
        cin >> v[i];
        f[i] = 1;
    }

    int res = 0;
    int t = v[1][v[1].size()-1] - '0';
    pre[t] = 1, preLen[t] = 1;
    for(int i = 2; i <= n; ++i){
        int h = v[i][0] - '0', t = v[i][v[i].size()-1] - '0';
        f[i] = f[pre[h]]+1;
        res = max(res, f[i]);

        if(preLen[t] < f[i]) pre[t] = i, preLen[t] = f[i];
    }
    cout << n-res;
    return 0;
}

image

DP写法

也可以用DP改进

f[i][j]: 前i个字符串中, 以数字j结尾的接龙数列最大长度
最后只需要取max{f[n][0~9]}

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 1e5+10;
string v[N];
int f[N][10];	//f[i][j]: 前i个字符串中, 以数字j结尾的接龙数列最大长度

int main()
{
    int n;
    cin >> n;
    for(int i = 1; i <= n; ++i) cin >> v[i];

    for(int i = 1; i <= n; ++i){
        for(int j = 0; j <= 9; ++j) f[i][j] = f[i-1][j];
        int h = v[i][0] - '0', t = v[i][v[i].size()-1] - '0';
        
		f[i][t] = max(f[i][t], f[i-1][h]+1);
    }
    int res = 0;
    for(int i = 0; i <= 9; ++i) res = max(res, f[n][i]);
    
    cout << n-res;
    return 0;
}

标签:数字,数列,int,蓝桥,接龙,71,include,组省赛
From: https://www.cnblogs.com/Knight02/p/17300756.html

相关文章

  • 2023年第14届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组
    2023年第14届蓝桥杯大赛软件赛省赛C/C++大学B组试题A:日期统计(5)直接暴力,8个for+优化,2~5分钟跑完。答案:365点击查看代码#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;constintN=1e6+10,INF=0x3f3f3f3f;intmon[]={0,31,28,......
  • 2023年4月蓝桥杯B组A到G题解析
    试题A:阶乘求和本题总分:5分【问题描述】令S=1!+2!+3!+...+202320232023!,求S的末尾9位数字。提示:答案首位不为0。【答案提交】这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得......
  • 第十四届蓝桥杯大赛软件赛省赛C/C++大学生B组
    第十四届蓝桥杯大赛软件赛省赛C/C++大学生B组试题A:日期统计A题直接枚举即可,枚举日期,暴力匹配#include<iostream>#include<algorithm>#include<vector>usingnamespacestd;boolcheck(stringt){ if(t.substr(0,4)!="2023")returnfalse; stringmon=t.substr(4,2......
  • 大二蓝桥杯菜鸟的自我反省 & 未来计划
    悟已往之不谏知来者之可追保持你的决心!xilan:大学就像一个梦幻的泡泡,外面则是竞争残酷的社会。内心:想做动画/AI方向,简单的目标才能走得更深更远一定要去教室自习室!怀疑自己的时候看一看:zhuanlan.zhihu.com/p/479036890本周任务acwing:每日3题,笔记完成角色动画隔2天,跑一......
  • 2023年蓝桥杯软件类省赛 C/C++ B组 解析
    还有一题忘了题意是什么了,等拿到题面了再更中间的题目顺序也忘了,填空题的数据也暂时还没有,暂时只有简单的思路,包括后面大题数据范围和是否多组都有点记不清A将题面序列处理成数组放代码里直接枚举八个位置的\(O(n^8)\)复杂度对于\(n=100\)的范围显然本地跑也跑不出来但由......
  • 蓝桥杯 2022 省 B
    C-刷题统计https://www.luogu.com.cn/problem/P8780签到题,先大跨步对每周的题数取模,然后暴力计算最后一周需要做的题。intmain(){ i64a=read(),b=read(),n=read(); i64ans=n/(5*a+2*b)*7,rest=n%(5*a+2*b); for(inti=1;i<=5;i......
  • 蓝桥考试技巧
    蓝桥考试技巧256M预留一些堆外空间后大概剩200M考心态,多看几个题,每个题目都看看打表能写出来一个大概的算法就先写上回来再想一些特殊点、注意LL问题押题枚举进位制双指针算法前缀和二分区间DP(记忆化搜索)背包问题(有限制的选择最优化问题)(01,完......
  • 蓝桥-13届-青蛙过河
    看完没什么思路就类似于看完一个自然语言描述的问题后,没法把它转换编程模型题目的意思是y至少要多大,才能足够青蛙跳2x次因为跳跃过程是可逆的,于是能否往返跳2x次等价于同向跳2x次由于当y=n时,青蛙不需要踩任何石头直接跳过去,于是y一定是小于等于n的一个数照这个数我们可以使用......
  • [每天例题]蓝桥杯C语言 成绩分析
    蓝桥杯C语言成绩分析题目    题目分析1.每个学生的得分都是一个0到100的整数。2.输出三行。第一行包含一个整数,表示最高分。第二行包含一个整数,表示最低分。第三行包含一个实数,四舍五入保留正好两位小数,表示平均分。思路分析1.使用数组进行成绩输入,声明为i......
  • [蓝桥杯 2021 国 AB] 翻转括号序列(线段树上二分)
    [蓝桥杯2021国AB]翻转括号序列题目描述给定一个长度为\(n\)的括号序列,要求支持两种操作:将\(\left[L_{i},R_{i}\right]\)区间内(序列中的第\(L_{i}\)个字符到第\(R_{i}\)个字符)的括号全部翻转(左括号变成右括号,右括号变成左括号)。求出以\(L_{i}\)为左端点......