蓝桥杯每日一题:接龙数列

2024-03-20 18:36
文章标签 每日 蓝桥 数列 接龙

本文主要是介绍蓝桥杯每日一题:接龙数列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目来源:第十四届蓝桥杯软件赛省赛 B组

对于一个长度为 K K K 的整数数列: A 1 A_1 A1, A 2 A_2 A2 , … , A K A_K AK , 我们称之为接龙数列当且仅当 A i A_i Ai 的首位数字恰好等于 A i − 1 A_{i-1} Ai1 的末尾数字 ( 2 ≤ i ≤ K 2 \le i \le K 2iK) . 例如, 12, 23, 35, 56, 61, 11是接龙数列, 12, 23, 34, 56 不受接龙数列, 因为 56 的首位数字不等于 34 的末位数字. 所有长度为 1 的整数数列都是接龙数列

现在给定一个长度为 N N N 的数列 A 1 , A 2 , . . . , A N A_1, A_2,...,A_N A1,A2,...,AN , 请你计算最少从中删除多少个数, 可以使得剩下的数列是接龙数列

输入 : 第一行包含一个整数 N N N

第二行包含 N N N 个整数 A 1 , A 2 , . . . , A N A_1, A_2, ... , A_N A1,A2,...,AN

输出 : 一个整数代表答案

Input Sample :

5
11 121 22 12 2023

Output Sample :

1

题目问最少删除多少个数, 我们可以逆转一下思维, 就是算 N N N 个数最多可以组成多长的接龙数列, 得到的长度 l e n len len , N − l e n N - len Nlen 就是我们要的最少删除个数. 我们发现这其实就是最长上升子序列, 完全可以用 DP 来解决. 根据 DP 的知识我们可以知道, 最长上升子序列的状态转移方程应该是:

f i , j = m a x ( f i , j , f i − 1 , j + 1 ) f_{i, j} = max(f_{i, j}, f_{i - 1, j} + 1) fi,j=max(fi,j,fi1,j+1)

时间复杂度为 O ( N 2 ) O(N^2) O(N2) . 但是考虑到本题的数据范围 1e5 , 很明显我们不能直接用, 否则会tle. 必须得考虑优化

我们发现, 在这个接龙数列中, 我们只需要考虑数字的首位和末位, 其他的不用考虑. 那么我们只需要 0 ∼ 9 0\sim9 09 十个数字就可以表示所有状态 f [ i ] f[i] f[i] 表示以 i i i 结尾的接龙数列. 对于一个数可以看成 i . . . j i...j i...j ( i i i 为首位, j j j 为末位) , 从上一个结尾为 i i i 的状态转移, 转移方程为

f [ j ] = m a x ( f [ j ] , f [ i ] + 1 ) f[j] = max(f[j], f[i] + 1) f[j]=max(f[j],f[i]+1)

下面给出题解代码, 请注重思考, 不要无脑cv

#include <bits/stdc++.h>
using namespace std;
const int maxn = 55;
string s;
int res = INT_MAX, n, f[10];void io() {cin.tie(0);cout.tie(0);ios::sync_with_stdio(false);
}int main() {io();cin >> n;for (int i = 1; i <= n; i++) {cin >> s;f[s.back() - '0'] = max(f[s.back() - '0'], f[s.front() - '0'] + 1);}for (int i = 0; i < 9; i++) {res = min(res, n - f[i]);}cout << res << '\n';return 0;
}

这篇关于蓝桥杯每日一题:接龙数列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/830380

相关文章

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

每日一练7:简写单词(含链接)

1.链接 简写单词_牛客题霸_牛客网 2.题目 3.代码1(错误经验) #include <iostream>#include <string>using namespace std;int main() {string s;string ret;int count = 0;while(cin >> s)for(auto a : s){if(count == 0){if( a <=

【每日刷题】Day113

【每日刷题】Day113 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 91. 解码方法 - 力扣(LeetCode) 2. LCR 098. 不同路径 - 力扣(LeetCode) 3. 63. 不同路径 II - 力扣(LeetCode) 1. 91. 解码方法 - 力扣(LeetCode) //思路:动态规划。 cl

C语言蓝桥杯

一、语言基础 竞赛常用库函数 最值查询 min_element和max_element在vector(迭代器的使用) nth_element函数的使用 例题lanqiao OJ 497成绩分析 第一种用min_element和max_element函数的写法 第二种用min和max的写法 二分查找 二分查找只能对数组操作 binary_s

力扣 739. 每日温度【经典单调栈题目】

1. 题目 理解题意: 1.1. 给一个温度集合, 要返回一个对应长度的结果集合, 这个结果集合里面的元素 i 是 当前 i 位置的元素的下一个更高温度的元素的位置和当前 i 位置的距离之差, 若是当前元素不存在下一个更高温度的元素, 则这个位置用0代替; 2. 思路 本题用单调栈来求解;单调栈就适用于来求当前元素左边或者右边第一个比当前元素大或者小的元素;【单调栈:让栈中的元素保持单调

每日一题——第八十一题

打印如下图案: #include<stdio.h>int main() {int i, j;char ch = 'A';for (i = 1; i < 5; i++, ch++){for (j = 0; j < 5 - i; j++){printf(" ");//控制空格输出}for (j = 1; j < 2 * i; j++)//条件j < 2 * i{printf("%c", ch

每日一题,力扣leetcode Hot100之238.除自身以外数组的乘积

乍一看这个题很简单,但是不能用除法,并且在O(N)时间复杂度完成或许有点难度。 考虑到不能用除法,如果我们要计算输出结果位置i的值,我们就要获取这个位置左边的乘积和右边的乘积,那么我新设立两个数组L和R。 对于L来说,由于表达的是位置i左边的数的乘积,那么L[0]=1,因为第一个数字左边没数那么为了不影响乘积初始值就设置为1,那么L[1]=L[0]*nums[0],那么L[i]=L[i-1

英语每日一段 195

Promising economic indicators won’t instantly reverse the lingering impact of hard times for millions of families, workplace culture expert Jessica Kriegel said. “Perception and reality are sometimes

UVa 10820 Send a Table (Farey数列欧拉函数求和)

这里先说一下欧拉函数的求法 先说一下筛选素数的方法 void Get_Prime(){ /*筛选素数法*/for(int i = 0; i < N; i++) vis[i] = 1;vis[0] = vis[1] = 0;for(int i = 2; i * i < N; i++)if(vis[i]){for(int j = i * i; j < N; j += i)vis[j] =