ural 2004. Scientists from Spilkovo 构造

2004. Scientists from Spilkovo

Time limit: 0.5 second
Memory limit: 64 MB
Misha and Dima are promising young scientists. They make incredible discoveries every day together with their colleagues in the Spilkovo innovative center. Now Misha and Dima are studying the properties of an amazing function  F which is written as follows.
C++:
int F(int x, int n)
{
    return (((x & ((1 << (n / 2)) - 1)) << ((n + 1) / 2)) | (x >> (n / 2)));
}
Pascal:
function F(x, n: integer): integer;
begin
    F := (((x and ((1 shl (n div 2)) - 1)) shl ((n + 1) div 2)) or (x shr (n div 2)));
end;
The friends want to perform the following computational experiment.
  1. All integers from 0 to 2n − 1 are written.
  2. Each integer x is replaced by F(xn).
  3. Each integer obtained after step 2 is written as a binary string of length n (if the integer has less than n bits, some leading zeroes are added; if the integer has more than n bits, only last nbits are written).
  4. The result of the experiment is a binary string of minimum length, that contains all the strings obtained after step 3 as its substrings.
If you can perform this experiment, maybe you are able to work in Spilkovo too!

Input

The only line contains an integer  n (1 ≤  n ≤ 20).

Output

Output the required binary string. If there are several optimal solutions, you may output any of them.

Sample

input output
1
10




题意:  输入一个n,然后把0-2^n-1 ,一次做为x  带入F ( x , n ) ,然后把得到的数转化为长度为n的二进制数 字符串。然后构造一条最短的二进制数,里面的子串要包含所有之前的到的二进制数 字符串。 

做法:暴力一下发现 处理过后 数字还是 0-2^n-1;

 那么那n=3 为例,就要构造出含有以下 二进制字符串 的字符串:

000

001

010

011

100

101

110

111


从111开始,然后从第二个数位开始 ,至末尾,再添加一个二进制数 0 或1, 要求新得到的是未出现的二进制字符串。

111后面可以添加0 ,也可以添加1, 试过之后发现 应要尽量先添加0,不然构造不出来。

构造过程:

1110

11100      因为100没出现过所以还可以添加0

111000  

1110001  000之前出现过了,所以不能加0 ,

11100010

111000101    100出现过了 所以添加1

1110001011    这就是最后构造出来的答案。


int vis[(1<<20)+10];
 
int main()
{
	int x,n; 
	string str;
	while(scanf("%d",&n)!=EOF)
	{
		
		memset(vis,0,sizeof vis);
		str.clear();
		int lim=1<<n;
		str.insert(0,n,'1');
		vis[lim-1]=1;
		
		int last=n-1;
		for(int i=0;i<lim-1;i++)
		{
			int cur=last-n+2;
			int new_last=cur+n-1;
			int tem=0;
			for(int i=cur;i<new_last;i++)
			{
				tem+=str[i]-'0'; 
				tem<<=1;
			}
			
			if(vis[tem])
				str+='1';
			else
				str+='0'; 
			vis[tem]=1;
			last++;
		} 
		cout<<str<<endl;
	}
	return 0;
}








  





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值