题目
给定一个N位的二进制串
b1 b2 … bN-1 bN
将该串做旋转,即将b1移到bN后面,得到一个新的二进制串:
b2 … bN-1 bN b1
对新的二进制串再做旋转,得二进制串
b3 b4 … bN-1 bNb1 b2
重复旋转操作操作,可得N个二进制串,对这N个串排序,可得一个N*N的矩阵
例如:
1 0 0 0 1 ->
0 0 0 1 1 ->
1 1 0 0 0 ->
0 0 1 1 0 ->
0 1 1 0 0
对它们做排序,得矩阵
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
问:给定这种矩阵的最后一列,求出矩阵的第一行。
对于上面的例子,给出 1 0 0 1 0,要你的程序输出 0 0 0 1 1。
代码
1 #include <stdio.h>
2
3 #define NMAX 100
4
5 int main(){
6 int i, j, none, total;
7 char input[NMAX], one[NMAX], *p;
8 int next[NMAX];
9 j = total = none = 0;
10
11 printf("Please input your sequence of [01]: ");
12 scanf("%s", &input);
13 p = input;
14 while(*p){
15 if(*p == '0')
16 next[j++] = total;
17 else if(*p == '1')
18 one[none++] = total;
19 total++;
20 p++;
21 }
22
23 for(i = 0; i < none; i++)
24 next[j++] = one[i];
25
26 printf("\nHere is your input: \n%s\n", input);
27
28 printf("\nHere is the first line:\n");
29 for(i = j = 0; i < total; i++)
30 printf("%c",input[j = next[j]]);
31 printf("\n");
32
33 return 0;
34 }
算法描述:
1.计算输入列中0和1的个数,并用它们形成第一列.
2.生成一个Next数组,使得数组中的i个0指向最后一列第i个0的行数,数组中的第j个1指向最后一列第j个1的行数.
3.从第1行开始,按照Next指引的顺序 – 从k到Next[k], 每次把该行最后一列的数字取出生成第一行的相应数字。
例如 输入 10010
1. 有3个0,2个1,所以第1列一定是
0
0
0
1
1
2. 生成Next数组 Next
1 0 1 2
2 0 0 3
3 0 0 5
4 1 1 1
5 1 0 4
3. 沿着Next,根据 输入列,生成第一行
0 0 0 1 1
原理:
对于序列(1) b1 b2 … bN-1 bN,左旋一位变成(2) b2 … bN-1 bN b1 ,我们只要知道(1)左旋后得到的(2)在矩阵中是哪一行,就可以根据该行第一列的值得到 b2,依次类推得到b3 , b4 , …
即:
假设矩阵中两行都以0开始,则它们左旋后,前后次序不变,所以在矩阵中以0开始的第1行,它的左旋后的序列在最后一列的第一个0的行。对1开始的行有同样的性质。