题目
问题描述
小蓝有一个 01 串 s = s1s2s3 ⋅ ⋅ ⋅ sn。
以后每个时刻,小蓝要对这个 01 串进行一次变换。每次变换的规则相同。
对于 01 串 s = s1s2s3 ⋅ ⋅ ⋅ sn,变换后的 01 串s’ = s’1s’2s’3 ⋅ ⋅ ⋅ s’n为:
s’1=s1;
s’i=si-1⊕si。
其中 a ⊕ b 表示两个二进制的异或,当 a 和 b 相同时结果为 0 ,当 a 和 b
不同时结果为 1。
请问,经过 t 次变换后的 01 串是什么?
输入格式
输入的第一行包含两个整数 n,t,分别表示 01 串的长度和变换的次数。
第二行包含一个长度为 n 的 01 串。
输出格式
输出一行包含一个 01 串,为变换后的串。
测试样例1
输入:
5 3
10110
输出:
11010
解释:
初始时为 10110,变换 1 次后变为 11101,变换 2 次后变为 10011,变换 3 次后变为 11010。
评测用例规模与约定
对于 40% 的评测用例,1 ≤ n ≤ 100 , 1 ≤ t ≤ 1000。
对于 80% 的评测用例,1 ≤ n ≤ 1000 , 1 ≤ t ≤ 10^9。
对于所有评测用例,1 ≤ n ≤ 10000 , 1 ≤ t ≤ 10^18。
思路
在t非常大的时候,代码长时间无法跑出结果。我有一个猜想,变换过程会不会有一个周期,设周期是z次,那变化z次,01串会变回初始状态。经过实验,发现确实存在一个周期,使得01串变为初试状态。由此,我的思路是先找到周期次数z的值,然后计算t%z。之所以要这样,是因为t对z取余得到了最终结果需要最初01子串变化的次数。然后再变化t%z次即可得到最终结果。
代码
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int main() {
long long n,t;
cin>>n>>t;
string s,s1,s2,s3;//s存储最初的01子串,s1存储s的第一位到最后一位用于异或计算,s2存储异或计算结果,s3存储最初的01子串。
cin>>s;
s3=s2=s;
long long i,j,zhouqi;
for(i=0;i<t;i++){
s1.insert(0, s, 0, n-1);
for(j=0;j<n;j++){
if(j==0)
s2[j]=s[j];
else{
if(s[j]==s1[j-1])//异或计算
s2[j]='0';
else
s2[j]='1';
}
}
s=s2;
if(s3==s){//计算周期次数zhouqi
zhouqi=i+1;
t=t%zhouqi+zhouqi;
}
s1.clear();
}
cout<<s;
return 0;
}
运行成功!