这题在我的洛谷博客上也有 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;//模拟完毕
}