专栏文章

题解:P11858 [CCC 2025 Senior] 破译 / Cryptogram Cracking Club

P11858题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mipzsgl1
此快照首次捕获于
2025/12/03 20:37
3 个月前
此快照最后确认于
2025/12/03 20:37
3 个月前
查看原文

思路

ss ' 中出现的整数的范围是 [11,101210 ^ {12}] ,展开后s长度甚至可以达到510165*10^ {16}, 所以明显这题需通过取模来获取答案
可以考虑先跑一遍 ss' ,将 ss 的长度 lonlon算出来; 如果 lonlon已经比 cc还要大的话,直接输出即可;不然就直接 cmod=lonc\bmod=lon,然后再跑一遍 ss' 即可。

代码

  1. 首先是对 ss' 中数字的取出,代码如下( ansans 储存的是 ss' 长度)
CPP
  s=s+" ",c++;//在s'后面加一个空格,不然最后一个数字会取不到;c++是因为s[0]是第一个字符
long long i=0,len=s.size(),number=0;//不开longlong见祖宗
string zm;//用于存储当前数字所对应的字母
while(i<=len)
{
  if(s[i]>='0' && s[i]<='9')
  number=number*10+s[i]-'0';//是数字取出就行
	else {//不是数字
		ans+=number;
		if(ans>=c){//如果已经达到了c,直接输出
			cout<<zm;
			return 0;
		}
		zm=s[i];
		number=0;
	}
  i++;
}
  1. 在完成数字的取出后,如果代码还没结束,说明字符串长度 ans>cans>c ;这时候如果一直往后搜索肯定不行的,取模可以解决一切
CPP
c%=ans;
取模之后, c<ansc<ans 是必然的,所以再次进行上面同样的操作必然可以找出答案
所以,直接重复上面的操作(一摸一样的,注意重新初始化哦)就可以了
但是,有一个小细节,如果没有注意到就会只有6分,如果 ccansans 的倍数,那么 cc%ans 就会是 00 ,而第 00 个数是取不到的!所以要特判!
CPP
if(c==0) c=ans;

完整代码

CPP
#include<bits/stdc++.h>
using namespace std;
string s;
long long c,ans=0;
int main()
{
	cin>>s>>c;
	s=s+" ",c++;
	long long i=0,len=s.size(),number=0;
	string zm;
	while(i<=len)
	{
		if(s[i]>='0' && s[i]<='9')
			number=number*10+s[i]-'0';
		else {
			ans+=number;
			if(ans>=c){
				cout<<zm;
				return 0;
			}
			zm=s[i];
			number=0;
		}
		i++;
	}
	c=c%ans;
	//重开 
	if(c==0) c=ans;
	i=0,number=0,ans=0;
	zm="";
	while(i<=len)
	{
		if(s[i]>='0' && s[i]<='9')
			number=number*10+s[i]-'0';
		else {
			ans+=number;
			if(ans>=c){
				cout<<zm;
				return 0;
			}
			zm=s[i];
			number=0;
		}
		i++;
	}
        return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...