[SCOI2005]超级格雷码

link

并不难的构造题。

实在不行可以观察数据。某一列的数字对应下来是会有规律的,都是从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;
}
posted @ 2022-07-05 14:10  Feyn618  阅读(27)  评论(0编辑  收藏  举报