C - Tautonym Puzzle
Time limit : 2sec / Memory limit : 256MB
Score : 1000 points
Problem Statement
We will call a string x good if it satisfies the following condition:
- Condition: x can be represented as a concatenation of two copies of another string y of length at least 1.
For example, aa
and bubobubo
are good; an empty string, a
, abcabcabc
and abba
are not good.
Eagle and Owl created a puzzle on good strings. Find one string s that satisfies the following conditions. It can be proved that such a string always exists under the constraints in this problem.
- 1≤|s|≤200
- Each character of s is one of the 100 characters represented by the integers 1 through 100.
- Among the 2|s| subsequences of s, exactly N are good strings.
Constraints
- 1≤N≤1012
Input
Input is given from Standard Input in the following format:
N
Output
In the first line, print |s|, the length of s. In the second line, print the elements in s in order, with spaces in between. Any string that satisfies the above conditions will be accepted.
Sample Input 1
7
Sample Output 1
4 1 1 1 1
There are two good strings that appear as subsequences of s: (1,1) and (1,1,1,1). There are six occurrences of (1,1) and one occurrence of (1,1,1,1), for a total of seven.
Sample Input 2
299
Sample Output 2
23 32 11 11 73 45 8 11 83 83 8 45 32 32 10 100 73 32 83 45 73 32 11 10
思路:考虑构造一个数列,右半部分为升序例如1,2,3,4,5,左半部分也为1~5的某种排列,其上升子序列的数目决定了整个数列的good序列数,因此题目转化为构造出合适的左半部分的排列。
先找规律
上升子序列数:与上一排列的差值:排列
1:1:1
3:2:1 2
7:4:1 2 3
15:8:1 2 3 4
2^n-1:2^(n-1):1 2 3 ... ...n
于是就容易解决了,将N转换成二进制,比如13(1101),等于1000+0100+0001,先考虑1000(8),为上面中1,2,3的排列数+1,因此为方便处理先将N+1,14(1110)=1000+0100+0010,主线是先构造出形如1,2,3升序的序列,同时在构造过程插入一些数满足0100和0010,具体看代码。
//reference:wtl666wtl
# include <stdio.h>
int a[103], b[103];
int main()
{
int p1=0, p2=0, m=100;
long long n;
scanf("%lld",&n);
++n;
while(n > 1)
{
if(n&1) a[++p1] = m--, --n;
else b[++p2] = m--, n>>=1;
}
printf("%d\n",p1+p2<<1);
for(int i=1; i<=p1; ++i)
printf("%d ",a[i]);
for(int i=p2; i>=1; --i)
printf("%d ",b[i]);
for(int i=101-p1-p2; i<=100; ++i)
printf("%d ",i);
puts("");
return 0;
}