Problem A. Googol String
Small input 7 points |
|
Large input 12 points |
|
Problem
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
becomes1
and every1
becomes0
. For example, "100" becomes "011". - reverse: The string is reversed. For example, "100" becomes "001".
Consider this infinite sequence of 0/1 strings:
S0 = ""
S1 = "0"
S2 = "001"
S3 = "0010011"
S4 = "001001100011011"
...
SN = SN-1 + "0" + switch(reverse(SN-1)).
You need to figure out the Kth character of Sgoogol, where googol = 10100.
Input
The first line of the input gives the number of test cases, T. Each of the next T lines contains a number K.
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.
Limits
1 ≤ T ≤ 100.
Small dataset
1 ≤ K ≤ 105.
Large dataset
1 ≤ K ≤ 1018.
Sample
其实,我们可以发现,每个字符串都是成倍+1的增长,如果是在中心点(也就是2^n -1)则一定就是0,否则的话,按中心点对称,就是转化为2^n -2 - k;这样,很快就会变的很小或者为中心点,再记录翻转的次数,也就是这样转化的次数,如果是奇数次就是1,否则就是0,直接得到答案了。复杂度为o(log(k));
#define N 205
#define M 100005
#define maxn 205
#define MOD 1000000000000000007
int n,T;
ll p[100];
ll k;
int main()
{
//freopen("A-large.in", "r", stdin);
//freopen("A-large.out", "w", stdout);
p[0] = 1;
For(i,1,100){
p[i] = p[i-1] * 2;
printf("%lld %d\n",p[i],i);
}
while(S(T)!=EOF)
{
For(ta,1,T+1){
scanf("%lld",&k);k--;
int flag = 0,num = 0;
bool isEnd = false;
while(k){
//printf("%lld k ",k);
For(i,0,100){
if(p[i] - 2 >= k){
flag = i;
break;
}
}
if(k == p[flag] - 2ll - k){
isEnd = true;
}
if(isEnd) break;
num++;
k = p[flag] - 2ll - k;
}
//printf(" num %d ",num);
if(!(num & 1))
printf("Case #%d: 0\n",ta);
else
printf("Case #%d: 1\n",ta);
}
}
//fclose(stdin);
//fclose(stdout);
return 0;
}