旋转的二进制
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
Problem Description
给定一个自然数M,及其二进制长度N,得到一个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
问:给出一个自然数M,及其二进制长度N,求出排序矩阵的最后一列。
对于上面的例子,给出M=3,N=5,要你的程序输出10010。
Input
第一行有一个自然数K,代表有K行测试数据(K<=1000)。 第二行至第K+1行,每行的第一个为自然数M,第二个为二进制长度N(N<64)。
Output
输出K行,每行N个二进制,表示矩阵最后一列从上到下的二进制。
Sample Input
3 3 5 4 7 1099512709120 45
Sample Output
10010 1000000 110000000000000000000000000000100000000000000
主要使用了位操作,模拟得出结果,注意在输入了m之后,考虑到n可能与m的实际二进制长度不符(大或小),所以我用了一个循环来确定rem[0]的值。
还有在对1进行<<操作时,要先将其做类型转换,否则系统会将其默认为int而导致出错
代码:
#include <iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
unsigned long long rem[70];
int main()
{
unsigned long long num;
unsigned long long m,n;
cin>>num;
while(num--)
{
cin>>m>>n;
memset(rem,0,sizeof(rem));
for(unsigned long long i=1;i<(unsigned long long(1)<<n);i=(i<<1))
{
if((i&m)>0) rem[0]=(rem[0]|i);
}
// rem[0]=m;
unsigned long long hed=(unsigned long long(1)<<(n-1)),bac;
for(int i=1;i<n;++i)
{
rem[i]=(rem[i-1]<<1);
if((rem[i-1]&hed)>0)
{
bac=1;
unsigned long long tem=(unsigned long long(1)<<n);
if(rem[i]>=tem)
rem[i]=rem[i]-tem;
}
else
{
bac=0;
}
rem[i]=rem[i]|bac;
}
sort(rem,rem+n);
for(int i=0;i<n;++i)
{
cout<<(rem[i]&1);
}
cout<<endl;
}
return 0;
}