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=0;
char last=' ',ch=getchar();
while(ch<'0'||ch>'9') last=ch,ch=getchar();
while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
if(last=='-') ans=-ans;
return ans;
}
const int maxn=65540;
string s[maxn],a[maxn];
int n,b,tot=1,cnt=1;
bool flag=0;
char chang(int x)
{
char p;
if(x<=9) p=(char)(x+48);
else{
p=(char) 65+x-10;
}
return p;
}
void work1(int k)
{
char p=chang(k);
for(int i=1;i<=tot;i++){
s[cnt]=p+a[i];
cnt++;
}
}
void work2(int k)
{
char p=chang(k);
for(int i=tot;i>=1;i--){
s[cnt]=p+a[i];
cnt++;
}
}
int main()
{
n=read();b=read();
tot=b;
for(int i=1;i<=tot;i++){
char p=chang(i-1);
s[i]+=p;
}
for(int t=2;t<=n;t++){
flag=0;
cnt=1;
for(int i=1;i<=tot;i++) a[i]=s[i];
for(int k=0;k<b;k++){
if(flag==0) work1(k);
else work2(k);
flag^=1;
}
tot=cnt-1;
}
for(int i=1;i<=tot;i++) cout<<s[i]<<"\n";
return 0;
}