异或变换 蓝桥杯 第十二届国赛H题

题目

问题描述

小蓝有一个 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;
}

运行成功!
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值