P2328 [SCOI2005]超级格雷码
暴力出奇迹喵!
这是一道模拟题
你会发现和 P5657 格雷码【民间数据】有异曲同工之妙,这道题直接按照上边链接题目的操作步骤 暴力模拟 就可以啊
我们观察 n=2n=2n=2 时候格雷码是这样操作的
在线引用链接题面描述:
带大家模拟一下:
比如 n=4
先生成1位:
也就是 0,1,2,3
然后生成两位:
也就是先把上一层的复制下来,顺序排好,然后再逆序排一遍,然后再顺序排一遍,再逆序排一遍。。。然后一小层作为一个分界,每一层的最左端都依次加上相应的字符 0,1,2,,,n-1
00 , 01 , 02 , 03 ,
13 , 12 , 11 , 10 ,
20 , 21 , 22 , 23 ,
33 , 32 , 31 , 30
n,B取其他值的时候也是一样的模拟
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
#include<queue> using namespace std; typedef long long ll; inline int read()
{
int ans=;
char last=' ',ch=getchar();
while(ch<''||ch>'') last=ch,ch=getchar();
while(ch>=''&&ch<='') ans=ans*+ch-'',ch=getchar();
if(last=='-') ans=-ans;
return ans;
} const int maxn=;
string s[maxn],a[maxn];
int n,b,tot=,cnt=;
bool flag=; char chang(int x)
{
char p;
if(x<=) p=(char)(x+);
else{
p=(char) +x-;
}
return p;
} void work1(int k)
{
char p=chang(k);
for(int i=;i<=tot;i++){
s[cnt]=p+a[i];
cnt++;
}
} void work2(int k)
{
char p=chang(k);
for(int i=tot;i>=;i--){
s[cnt]=p+a[i];
cnt++;
}
} int main()
{
n=read();b=read();
tot=b;
for(int i=;i<=tot;i++){
char p=chang(i-);
s[i]+=p;
}
for(int t=;t<=n;t++){
flag=;
cnt=;
for(int i=;i<=tot;i++) a[i]=s[i];
for(int k=;k<b;k++){
if(flag==) work1(k);
else work2(k);
flag^=;
}
tot=cnt-;
}
for(int i=;i<=tot;i++) cout<<s[i]<<"\n";
return ;
}