当前位置: 首页 > news >正文

信奥赛CSP-J复赛集训(DP专题)(14):P7158 「dWoi R1」Password of Shady

信奥赛CSP-J复赛集训(DP专题)(14):P7158 「dWoi R1」Password of Shady

在这里插入图片描述

题目背景

天海兰太郎被杀后,最原看到图书架后面刷卡器里的尘土并没有消散,陷入了沉思 ……

最原在想,黑幕是如何做到刷卡器的尘土没有消散但是还成功进入了黑幕的房间呢?然后他再次确认了刷卡器,发现了一个密码盘,密码盘下写着一行文字「真正的秘密总是被谎言欺骗,但黑幕不至于欺骗自己」,然后还有一道题,于是最原要用 1min 的时间解出这道题。

题目描述

这道题要求最原构造一个 n n n 位数,并且满足以下两个要求:

  • 「强者从不说废话」,代表着这个数没有前导零, 0 0 0 没有前导零且是一位数。
  • 「强者善于成 k k k 对合作」,代表着这个数的所有数位中有偶数个 k k k 0 0 0 是偶数。

最原很快就让入间制作了一个造数器,但是造数器还需要输入有多少个满足要求的数,于是他就求助于了你,因为做造数器已经用了 59.5s,所以他想让你 0.5s 求出有多少个符合要求的数。

答案对 998   244   353 998\ 244\ 353 998 244 353 取模。

输入格式

本题多测,测试组数为 t t t
对于每组数据,一行两个整数 n , k n,k n,k

输出格式

对于每组数据,一行一个整数代表答案。

输入输出样例 #1

输入 #1

2
2 3
11 4

输出 #1

73
842367440

说明/提示

样例 1 解释

第一组数据,满足要求的数为:

  • 0 0 0 3 3 3 10 ∼ 12 10\sim 12 1012 14 ∼ 22 14 \sim 22 1422 24 ∼ 29 24 \sim 29 2429 40 ∼ 42 40 \sim 42 4042 44 ∼ 52 44 \sim 52 4452 54 ∼ 62 54 \sim 62 5462 64 ∼ 72 64 \sim 72 6472 74 ∼ 82 74 \sim 82 7482 84 ∼ 92 84 \sim 92 8492 94 ∼ 99 94\sim 99 9499
  • 2 2 2 3 3 3 33 33 33

第二组数据的样例解释写了 114514 行,但赛前 0.1s 不小心被黑白熊偷走了,书虫来不及补了。

数据规模与约定

本题采用捆绑测试。

  • Subtask 1(5 pts): n = 1 n=1 n=1
  • Subtask 2(25 pts): n ≤ 6 n \le 6 n6
  • Subtask 3(25 pts): t ≤ 100 t \le 100 t100
  • Subtask 4(45 pts):无特殊限制。

对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 1 0 5 1 \le n \le 10^5 1n105 1 ≤ k ≤ 9 1 \le k \le 9 1k9 1 ≤ t ≤ 1 0 6 1 \le t \le 10^6 1t106


AC代码(100分)

#include<bits/stdc++.h>
using namespace std;
/*dp思路 
	1、同时记录更新两个状态
		dp1[i] :构造满足要求的i位数 
		dp2[i] :构造不满足要求的i位数 
	2、	一个满足要求的 i 位数,可以由一个满足要求的 i-1 位数加上一位除了 k 之外的数位得来
   			 或者以由一个不满足要求的 i-1 位数加上一位 k
		一个不满足要求的 i 位数,可以由一个不满足要求的 i-1位数加上一位除了 k 之外的数得来
   			 或者由一个满足要求的 i-1位数加上一位k 
	3、状态转移方程为:
		dp1[i] = dp1[i-1]*9 + dp2[i-1]
		dp2[i] = dp2[i-1]*9 + dp1[i-1]
*/
const int N=1e5+10;
int t,n,k; 
long long dp1[N],dp2[N];//注意开long long 
int main(){
	//用dp递推出1~10^5的所有答案
	dp1[1]=8;//1位数比较特殊,初始时不考虑0 
	dp2[1]=1; 
	for(int i=2;i<=100000;i++){
		dp1[i] = (dp1[i-1]*9 + dp2[i-1])%998244353;
		dp2[i] = (dp2[i-1]*9 + dp1[i-1])%998244353;
	}
	//输出答案 
	cin>>t;
	while(t--){
		scanf("%d%d",&n,&k);//t范围较大,不用cin 
		if(n==1) printf("9\n"); //特判1位数 
		else printf("%lld\n",dp1[n]); //t范围较大,不用cout
	}
	return 0;
}  

文末彩蛋:

关注并查看老师的个人主页,学习完整csp信奥赛完整系列课程: https://edu.csdn.net/lecturer/7901

在这里插入图片描述

相关文章:

  • JavaScript 知识点整理
  • AI赋能低代码平台可行性研究报告
  • docker学习笔记(1)从安装docker到使用Portainer部署容器
  • AI数据分析:deepseek生成SQL
  • Docker 学习(三)——数据管理
  • 《Operating System Concepts》阅读笔记:p180-p187
  • 【C++】当一个类A中没有声明任何成员变量和成员函数,sizeof(A)是多少?
  • shell文本处理
  • 深度学习的隐身术:详解 PyTorch nn.Dropout
  • Scala:for 循环遍历形式基本简单介绍(基础,高级,for-yield,特殊场景)
  • 如何将本机的vm中linux拷贝给别人使用
  • 快速高效使用——阿里通义万相2.1的文生图、文生视频功能
  • 敏捷开发学习笔记
  • 汽车智能钥匙低频PKE天线
  • 【商城实战(2)】商城架构设计:从底层逻辑到技术实现
  • 局部变量占用空间
  • deepseek免费网站大全
  • css学习第四章之常用属性(第一节)
  • github进不去,一直显示错误
  • vue下载文件 (blob文件流) 及 下载失败报错信息处理
  • 北京网站建设方案/如何写营销软文
  • seo网站优化方案/站内营销推广方案
  • jtbc网站内容管理系统/微商软文推广平台
  • 创业型企业网站模板/关键词排名零芯互联关键词
  • 输入法网站设计/电子商务网站建设多少钱
  • 网站建设工作报告/seo研究协会网