暴力肯定是无法做的
当时做的时候 当成一道递推来做的 用到分治的思想
想象一串长度为2n+1的列
那么前n个为前一串数 后n个是前一串数的reverse
第n+1个数 为第几串的编号
例如
第几串 中间的那个数 中间那个数的位置 长度
1 1 1 1
2 2 2 3
3 3 4 7
n n 2^(n-1) 2*len(n-1)+1
可以发现中间那个数总是代表了这一列个特征
那么把第n串的第1-2^(n-1)个数化为这个串都有效部分 因为后n个是前一串数的reverse
那么一个串的有效长度就是len[n] = 2^(n-1)
所以 给定第k个数当 k > 2^(n-1)时 可以把 它归结于前串的位置 是2*len[n] - k
当k == len[n] 的时候说明刚好 选择的就是这串的特征数(中间那个数)
否则 k < len[n] 那么就讨论 k 与 len[n-1]的情况 知道k == len[n] n就是这个数的大小
1 #include <iostream> 2 #include <stdio.h> 3 #include <string> 4 #include <string.h> 5 #include <map> 6 #include <queue> 7 #include <fstream> 8 #define READ() freopen("in.txt", "r", stdin); 9 10 using namespace std; 11 12 int main() 13 { 14 int n; 15 long long k; 16 string str = "1"; 17 long long len[128];//有效长度 18 for (int i = 1; i <= 51; i++) 19 { 20 if (i == 1) len[i] = 1; 21 else len[i] = 2*len[i-1]; 22 } 23 scanf("%d%lld", &n, &k); 24 while (k != len[n] ) 25 { 26 if (k > len[n]) k = 2*len[n] - k; 27 n--; 28 } 29 cout << n << endl; 30 }