2020浙江理工新生赛,小白的笔记
题目1:4521: Clytxdy
Cly成天说自己是个cdd,但这显然是假的,我们都知道clytxdy,为了验证cly到底是cdd还是txdy,请你破解以下问题。
给你一个字符串,请检查其中子序列clycdd和clytxdy出现次数,输出出现次数多的那个,如果出现次数一样,那当然是输出clytxdy,为了方便计算,你只需要比较出现次数对998244353取余后的结果。
解题思路
使用动态规划,倒着递归即可
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
const int maxn = 1e5+100;
const int mod = 998244353;
char ch[maxn];
const char a[8]="clycdd",b[8]="clytxdy";
ll sum1[9]={1},sum2[9]={1};
int main(){
int i,j;
scanf("%s",ch+1);
int len = strlen(ch+1);
int len1 = strlen(a);
int len2 = strlen(b);
for(i=1;i<=len;i++){
for(j=len1;j>=1;j--)if(ch[i]==a[j-1])sum1[j]=(sum1[j]+sum1[j-1])%mod;
for(j=len2;j>=1;j--)if(ch[i]==b[j-1])sum2[j]=(sum2[j]+sum2[j-1])%mod;
}
if(sum2[len2]>=sum1[len1])printf("clytxdy\n");
else printf("clycdd\n");
return 0;
}
写代码过程中遇到的问题
- 字符串地址
ch+1
写成&ch[1]
,导致运算量增加 - 将
strlen()
函数写到了if的判断语句里,导致运行超时 sum[j] = (sum[j] + sum[j-1])%mod
写为sum[j] += sum[j-1]%mod
,导致结果错误
题目二:4522: Cly的博弈
Cly很喜欢博弈,这天他和他的分身DD_BOND玩起了一个博弈游戏(本体当然是先手了),游戏规则如下,请你判断谁能赢得游戏。
最初有一个数字n,每次操作可以选择一个数字x满足0<x<n,且n%x==0,接着用n-x替换原本数字,谁不能操作谁就输了。
对于每次询问如果先手能赢,你需要告诉cly第一步能选择的最大x是什么,为了方便起见,你最后只需要告诉他所有询问x的和就行了。
解题思路
发现偶数一定可变奇数,奇数只能变偶数,第一步选择最大奇因子即可
代码
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
const int maxn = 1e5+5;
int main(){
int n,p,sum=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&p);
if(p&1){
printf("DD_BONDNB\n");
}
else {
printf("clynb\n");
while(p%2==0)p/=2;
sum+=p;
}
}
printf("%d\n",sum);
return 0;
}
题目3:4532: DD_BOND之梦境之战
梦境之路上有n盏灯,其中有亮有灭,双方依次从起点开始选择任意盏灯点亮或熄灭,但尽头的那盏必须是被从点亮状态熄灭,第一个熄灭所有灯的人会坠出梦境。
书面一点说,DD_BOND会给你一个长为n的01串,0表示灯熄灭,1表示灯亮起,DD_BOND和lmb990607会依次选择任意长度但必须是以1结尾的前缀,将它们取反(0->1,1->0),而第一个让整个串都变成0的人就会失败。
现在DD_BOND想知道自己是否有必胜的方法。
解题思路
每次操作都会改变第一盏灯的亮灭情况,输的人必会熄灭第一盏灯,故只要判断第一盏灯的亮灭即可