poj1147 Binary Codes

    技术2022-05-19  24

    这道题真的很经典!

    首先我们只知道矩阵的最近一列,但我们容易得出矩阵的第一列——若有‘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; }

     


    最新回复(0)