1147:Binary codes
总时间限制:
1000ms
内存限制:
65536kB
描述
给定一个N位的二进制串
b1 b2 ... bN-1 bN
将该串做旋转,即将b1移到bN后面,得到一个新的二进制串:b2 b3 ... bN-1 bN b1
对新的二进制串再做旋转,得二进制串b3 b4 ... bN-1 bN b1 b2
重复旋转操作操作,可得N个二进制串,对这N个串排序,可得一个N*N的矩阵
例如:
1 0 0 0 1->0 0 0 1 1->0 0 1 1 0->0 1 1 0 0->1 1 0 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。
输入
第一行有一个整数 N 表示二进制串的长度(N <= 3000)
第二行有N个整数,表示矩阵最后一列从上到下的数值。
输出
输出N个整数,表示矩阵第一行从左到右的数值。
样例输入
5
1 0 0 1 0
样例输出
0 0 0 1 1
来源
IOI 2001 备选题
/*
知道最后一列,那么由于每一列所含的数是相同的,而且又是排好序的,
所以可以确定第一列,是若干个0加之后若干个1,0的个数由最后一列确定。
把最后一列调到第一列,其实整个矩阵每一行所包含的序列整体不变,
只是行与行之间需要再排序才和原矩阵相同。此后由于除了第一列,之后都是排好的,
所以只要根据第一列的排序状况就可以确定第二列变成什么样子。这样不断地把最后一列
调到第一列,再行排序就可以得到原矩阵。于是只要根据题目给的最后一列,确定出其
排序的置换,再作用于第一列,就可以得出整个矩阵。由于只要求第一行,所以只要记录
每列第一个数的变换情况。
*/
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
using namespace std;
int n;
int a[3005];
int f[3005];
int main()
{
cin>>n;
int zero=0;
for(int i=1;i<=n;++i)
{
cin>>a[i];
}
for(int i=1;i<=n;++i)//构造下一列相对于上一列的置换f
{
if(a[i]==0)
{
f[++zero]=i;
}
}
for(int i=1;i<=n;++i)
{
if(a[i]==1)
{
f[++zero]=i;
}
}
int t=f[1];
for(int i=1;i<=n;++i)
{
cout<<a[t]<<" ";
t=f[t];
}
cout<<endl;
return 0;
}