Tautonym Puzzle
题意:
构造一个长度不超过200,数字不大于100的序列,使得合法子序列的个数恰好为N;
合法子序列是指一个长度为偶数的序列,前一半和后一半相等。
解法:
考虑这种构造方法
假设我们当前有序列为 $x_1, x_2, x_3, x_4, 1, 2, 3, 4$,有 $cnt$个
那么 $x_1, x_2, x_3, x_4, 5, 1, 2, 3, 4, 5$,有 $2cnt+1$ 个
$5 ,x_1, x_2, x_3, x_4, 1, 2, 3, 4, 5$,有 $cnt+1$ 个。
这样考虑递归
$solve(1) = {1}$
$solve(n) = solve(\frac{n-1}{2}) + {t}$
$solve(n) = {t} + solve(n-1)$
总共会有 $O(2 * logn)$ 个元素,数字大小为 $O(logn)$。
#include <bits/stdc++.h> #define LL long long #define N 110 using namespace std; deque<int> ans1,ans2; int modify[N],tot; void solve(LL n) { if(n==1) return; if((n-1)%2==0) { modify[++tot] = 1; solve((n-1)/2); } else { modify[++tot]=2; solve(n-1); } } int main() { LL n; cin>>n; int tim=1; solve(n); ans1.push_back(1); for(int i=tot;i>=1;i--) { if(modify[i]==1) ans1.push_back(++tim); else ans1.push_front(++tim); } cout<<2*(int)ans1.size()<<endl; for(int i=0;i<(int)ans1.size();i++) printf("%d ",ans1[i]); for(int i=0;i<(int)ans1.size();i++) printf("%d%c",i+1,i==((int)ans1.size())-1? '\n':' '); return 0; }