Description
A "0/1 string" is a string in which every character is either 0 or 1. There are two operations that can be performed on a 0/1 string:
switch: Every 0 becomes 1 and every 1 becomes 0. For example , "100" becomes "011" .
reverse: The string is reversed . For example , "100" becomes "001" .
Consider this infinite sequence of 0/1 string.
S0 = " "
S1 = "0"
S2 = "001"
S3 = "0010011"
S4 = "001001100011011"
........
S
n = S
n-1 + "0" + switch(reverse(S
n-1))
You nedd to figure out the K
th character of Sgoogol, where googol =10^100
Input
The first line of input gives the number of test cases, T(1<=T<=100). Each of the next T lines contains a number K (1<=K<=10^18).
Output
For each test case, output one line containing "Case #x: y", where x is the test case number(starting from 1) and y is the Kth character of Sgoogol.
Sample Input
4
1
2
3
10
Sample Output
Case #1: 0
Case #2: 0
Case #3: 1
Case #4: 0
// Sn = Sn-1 + "0" + Sn-1逆序再按位取反 ,求Sgoogol 第k位的字符是0还是1,googol = 10^100,实际上不用管googol的大小,观察可知,第k位
总是关于某个“0”与另一个位对称,且等于此位数字取反,若k在第Sn里面,则对称轴在Sn-1长度加1的位置, 不断递归即可。
#include "iostream"
using namespace std;
typedef long long ll;
int f(ll p,ll k) { //p 为Sn-1的长度
if(k == 1) return 0;
ll mid = p + 1;
ll k1 = mid - (k-mid); //求出对称的位置k1
if(mid == k) return 0; //若k即为对称轴位置,则一定为0
p = 1; // 由于递归求k1,则k1的p需要重新求
while(p < k1) {
p = p*2 + 1;
}
p = (p-1)/2;
return (f(p,k1) == 1)^1;
}
int main(){
ll k,p,t;
cin >> t;
int kase = 0;
while(t--) {
cin >> k;
p = 1;
while(p < k) { //求p
p = p*2 + 1;
}
p = (p-1)/2;
cout << "Case #" << ++kase << ": " << f(p,k) << endl;
}
}