ATCoder_contest_abc220
D-FG operation
题目描述
我们有一个包含N个整数的序列,每个整数在0~9之间(包含0和9):A = (,......,),被按照这个序列进行排列。我们将进行F操作和G操作,直到这个序列的长度为一。
- 操作F:删除最左端的两个数(x1,x2),将(x1+x2)%10加到序列的最左端
- 操作G:删除最左端的两个数(x1,x2),将(x1*x2)%10加到序列的最左端
对于每一个k = 0,1,2,...,9
在 2 的 N 次方减一种可能的方法中,有多少种操作方法,使得最后剩余的数字是 K。由于这个结果可能非常的大,请输出这个结果对998244353取模后的结果。
数据规模
2 <= N <= 1e5
0 <= <= 9
原题链接
Input
3 2 7 6
Output
1 0 0 0 2 1 0 0 0 0
Input
5 0 1 2 3 4
Output
6 0 1 1 4 0 1 1 0 2
题解思路
对于一个长度为 N 的序列,可以先考虑最前面的两项,然后结果存到第二个位置上,第二个位置上有两种可能,一是分别进行F和G操作是产生了两个不同的数字,二是产生了两个相同的数字。这个时候,虽然第二个位置有很多种情况,但是对于给定的,,我们一定可以算出所有的可能,然后拿位置上的所有可能与进行F,G操作,有可以算出来。然后要做的就是存了,我是开了一个arr[N][10]的数组,arr[i][9]表示把前 i-1 项消除之后第 i 位(即此时的第一位)剩余数字为 9,这样的方法有多少种。怎么更新呢?是个递推啊。假设arr[i-1][0~9]我们都知道,是题目给出的,我们拿对 0~9 分别进行F,G操作,比如 = 3,当他对 0 进行F操作时,结果为3,我就让arr[i][3] += arr[i-1][0],当进行G操作时,结果也为3,我们就再arr[i][3] += arr[i-1][0],其他数字亦是如此。也就是说我们知道前一个的结果,可以推出后一个的结果,上代码。
AC代码
#include <iostream> #define int long long using namespace std; const int N = 1e5 + 10; const int mod = 998244353; int arr[N][10],n; signed main(){ cin >> n; for(int i = 1; i <= n; i++){ int a; cin >> a; arr[i][a]++; //初始化,记录第 i 个位置 Ai 的值(做标记) } for(int i = 2; i <= n; i++){ int temp; for(int j = 0; j < 10; j++) if(arr[i][j] == 1) temp = j,arr[i][j] = 0; //取出Ai,并把arr[i][j]归零(删除标记) for(int j = 0; j < 10; j++){ arr[i][(j + temp) % 10] = (arr[i][(j + temp) % 10] + arr[i-1][j]) % mod; arr[i][(j * temp) % 10] = (arr[i-1][j] + arr[i][(j * temp) % 10]) % mod; } } for(int i = 0; i < 10; i++) cout << arr[n][i] << endl; return 0; }
本文作者:伍六柒-
本文链接:https://www.cnblogs.com/paper-plane/p/15349906.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效