[SCOI2005]超级格雷码
并不难的构造题。
实在不行可以观察数据。某一列的数字对应下来是会有规律的,都是从0到n-1,再从n-1到0,循环往复,只不过每一位的循环节长度不一样。这也很好理解,因为每一个数和前一个数只会有一个数字不一样,所以它肯定是这样的变化形式。然后输出就可以了。考场上debug了整整半个小时。维生素B。
#include<bits/stdc++.h>
//#define feyn
const int N=70010;
const int M=40;
using namespace std;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
int m,n,b[M];
char a[M],s[N][M];
signed main(){
#ifdef feyn
freopen("in.txt","r",stdin);
#endif
read(m);read(n);
for(int i=0;i<10;i++)a[i]='0'+i;
for(int i=10;i<=35;i++)a[i]='A'-10+i;
b[0]=1;
for(int i=1;i<=m;i++)b[i]=b[i-1]*n;
for(int i=1;i<=m;i++){//第几个
int len=b[m-i];
bool now=true;
for(int j=1;j<=b[m];j+=len*n){//字符块的块首
if(now){
for(int k=0;k<n;k++){//字符
for(int r=k*len+j;r<(k+1)*len+j;r++){//位置
s[r][i]=a[k];
}
}
}
else{
for(int k=n-1;k>=0;k--){//字符
int sss=k;k=n-k-1;
for(int r=k*len+j;r<(k+1)*len+j;r++){//位置
s[r][i]=a[sss];
}
k=sss;
}
}
now=now?false:true;
}
}
for(int i=1;i<=b[m];i++){
for(int j=1;j<=m;j++)putchar(s[i][j]);
putchar('\n');
}
return 0;
}
一如既往,万事胜意