poj 杂题 - 1147 Binary codes

N位的二进制串连续N次循环移位,得到N个二进制串。对其按照字典序排列,得到一个N*N的矩阵。告诉矩阵最后一列,求矩阵第一行。

拿这个题目例子讲解吧。

<span style="font-family:Microsoft YaHei;font-size:14px;">0	0	0	1	1
0	0	1	1	0
0	1	1	0	0
1	0	0	0	1
1	1	0	0	0</span>

 
我们看到最后一列是10010,因为是按照字典序排列,也就是0在1前面,那这个每一行的第一个数字肯定是从0到1的,因为是最高位嘛,所以我们将最后一列排序出第一列是00011。接下来就很神奇了。我们将最后一列的内容移到第一列,此时变成了: 
<span style="font-family:Microsoft YaHei;font-size:14px;">1	0	0	0	1	
0	0	0	1	1	
0	0	1	1	0	
1	1	0	0	0	
0	1	1	0	0	</span>
这时我们知道了变换后矩阵的第一列和第二列,而根据字典序,我们需要对第一列进行重排序,即12345(行)变成了23514(行),而第二列这样变化后成为了00101,我们拿这个与原先的第二列比较,是不是一样?而第三列变成了01100,第4列变成了11000,发现第三列和原先的第二列一样,第四列和原先的第三列一样。所以我们可以通过两列推出所有列的情况。

这样子其实就可以做了,我们发现了第一列和最后一列有这样的对应关系。这样我们可以用next数组记录每一个01的相对位置对应情况,最后按照next数组的对应关系输出即可。

<span style="font-family:Microsoft YaHei;font-size:14px;">#include<stdio.h>
#include<stdlib.h>
# define MAX 3002
int	data[MAX]={0};
int	data1[MAX]={0};
int	next[MAX]={0};
int cmp(const void *a ,const void *b){
	return *(int *)a - *(int *)b;
}
int main(){
	int n,i,zeroind=0,oneind=0,count,j;
	scanf("%d",&n);
	for(i=0;i<n;i++){
		scanf("%d",&data[i]);
		data1[i]=data[i];
	}
	qsort(data1,n,sizeof(int),cmp);
	for(i=0;i<n;i++){
		if(data1[i] == 0){
			for(j=zeroind;j<n;j++){
				if(data1[i]==data[j]) { next[i] = j; zeroind = j+1; break;}
			}
		}
		else{
			for(j=oneind;j<n;j++){
				if(data1[i]==data[j]) { next[i] = j; oneind = j+1; break;}
			}
		}
	}
	count =0;i=0;
	while(count < n-1){
		printf("%d ",data[next[i]]);
		i = next[i];
		count++;
	}
	printf("%d",data[next[i]]);
	printf("\n");
}</span>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值