CF989B A Tide of Riverscape

这题在我的洛谷博客上也有 https://www.luogu.org/blog/kyx0806/

这题就是一道模拟,要考虑的方面还是挺多的,坑。。也挺多的

附上代码,讲解在代码里

这题因为是输出随意一种所以有很多种做法,我的方法可能比较麻烦因为是错了几遍改了几遍后AC的

【仅供参考】

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <cmath>
using namespace std;
char s[2101];
int main()
{
    long long n,p,m=1,x;
    bool t=0,y=0;
    cin>>n>>p;
    for(int i=1;i<=n;i++)
    {
        cin>>s[i];
    }
    if(n==p)//如果长度和周期一样那就肯定没有不同的可能性了 
    {
        cout<<"No";
        return 0;
    }
    for(int i=1;i<=p;i++)//只循环一个周期就行,因为后面都是一样的 
    {
        m=i;//m表示判断位置,判断该位置有没有可能是那个不同的 
        while(m<=n&&(m+p<=n||m>p))//位置要比总长度小,m+p是下一个周期该位置,&&后面那一串表示m位置不能只有一个周期有,不然影响后面判断 
        {
            if(m+p<=n&&s[m+p]!=s[i]&&s[m+p]!='.'&&s[i]!='.')//如果不同周期相同位置不同,那总串肯定有不同的 
            {
                t=1;//t表示有不同的可能性 
                y=1;//这里设个旗帜,说明是这种方式判断有可能的 
                break;
            }
            else if(s[m]=='.')//如果多个周期里有一个问题有".",那就代表可以自由发挥了~~ 
            {
                t=1;//同上 
                x=m;//这里是记录一下在哪个位置判断有可能性,后面有用 
                break;
            }
            m+=p;//下一个周期相同位置 
        }
        if(t==1)//已经判断出来有可能性了,就不用继续循环了 
        {
            break;
        }
    }
    if(t==0)//循环一遍没判断出可能性 
    {
        cout<<"No";
        return 0;
    }
    else if(t==1&&y==0)//如果是用"."判断出有可能性的 
    {
        m=x;
        if(x+p<=n)//往后找,找不同的 
        {
            while(m<=n)
            {
                if(s[m]!='.')//找到一个不是点的,只要修改标记过的点让它跟后面的不一样就行 
                {
                    if(s[m]=='1') 
                    {
                        s[x]='0';
                        break;
                    }
                    else if(s[m]=='0')
                    {
                        s[x]='1';
                        break;
                    }
                }
                m+=p;
                if(m>n)//找了一圈没找到不是点的,说明所有周期这个位置都是点,那只要确保两个周期相同位置不同就行 
                {
                    s[x]='0';
                    s[x+p]='1';
                }
            }
        }
        else if(x+p>n)//如果这个"."在最后一个周期,就往前循环找 
        {             //这种情况判断很重要!我就曾经挂过这样一个点! 
            while(m>=1)
            {
                if(s[m]!='.')
                {
                    if(s[m]=='1')
                    {
                        s[x]='0';
                        break;
                    }
                    else if(s[m]=='0')
                    {
                        s[x]='1';
                        break;
                    }
                }
                m-=p;
            }
        }
    }
    for(int i=1;i<=n;i++)//前面已经确保有不同的了,剩下的点就用0填充就行,想用1也可以 
    {
        if(s[i]=='.')
        {
            s[i]='0';
        }
        cout<<s[i];
    }
    return 0;//模拟完毕 
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值