这道题真的很经典!
首先我们只知道矩阵的最近一列,但我们容易得出矩阵的第一列——若有‘0’,刚应该全在第一列的前面。例如
5
1 0 0 1 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
然后就是必须理解,假设第一列的三个‘0’是不同的,那么在最后一列,他们的相对顺序也是不变的,可以这样理解,也就是将前三行分别右移一位,‘0’也就到最后一列了,但这三行的相对大小不小,呵呵。。。‘1’也是一样的!
设first, last分别为第一列,最后一列,向量next为first, last元素之间的对应关系,例如上述矩阵
first=(0, 0, 0 , 1, 1)
last=(1, 0, 0, 1, 0)
注:下标从‘0’开始, 相同颜色代表对应!
向量next=(1,2,4,0,3)
因为矩阵右移一位后, first 就可以到last的右边了; first[i] = last[next[i]]; 这个式子就是对应关系! 然后就可以直接结果了, 第一行第一个元素为 first[0], 第二个元素在第一个基础上得到为first[next[0]](first列中第0号元素对应对应last列第next[0]号元素,取后者右端元素,在第一列,即first[next[0]])......
例如上述测试数据
k=0
k = next[k] k=1
k = next[k] k=2
... k=4
.... k=3
结果为0 0 0 1 1
#include<iostream> #include<fstream> using namespace std; int main() { int last[3001],first[3001],next[3001]; bool flag[3001]; int n; int i,j,k; ifstream fin("bit.in"); ofstream fout("bit.out"); while(cin>>n) { for(i=0; i<n; i++) flag[i] = false; int zero = 0; for(i=0; i<n; i++) { cin>>last[i]; if(last[i] == 0) zero++; } for(i=0; i<zero; i++) first[i] = 0; for(i=zero; i<n; i++) first[i] = 1; for(i=0; i<n; i++) { j=0; while(flag[j]==true || first[i] != last[j]) j++; next[i] = j; flag[j] = true; } k=0; for(i=0; i<n ; i++) { cout<<first[k]<<' '; k = next[k]; } cout<<endl; } return 0; }