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]<<" "; return 0; }