Round A APAC Test 2016 Problem A. Googol String

Problem A. Googol String

This contest is open for practice. You can try every problem as many times as you like, though we won't keep track of which problems you solve. Read the Quick-Start Guide to get started.
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 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 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


Input 
 

Output 
 
4
1
2
3
10

按题中要求构造字符串,问第k个是0还是1,

其实,我们可以发现,每个字符串都是成倍+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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值