B. Chloe and the sequence
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Chloe, the same as Vladik, is a competitive programmer. She didn’t have any problems to get to the olympiad like Vladik, but she was confused by the task proposed on the olympiad.
Let’s consider the following algorithm of generating a sequence of integers. Initially we have a sequence consisting of a single element equal to 1. Then we perform (n - 1) steps. On each step we take the sequence we’ve got on the previous step, append it to the end of itself and insert in the middle the minimum positive integer we haven’t used before. For example, we get the sequence [1, 2, 1] after the first step, the sequence [1, 2, 1, 3, 1, 2, 1] after the second step.
The task is to find the value of the element with index k (the elements are numbered from 1) in the obtained sequence, i. e. after (n - 1) steps.
Please help Chloe to solve the problem!
Input
The only line contains two integers n and k (1 ≤ n ≤ 50, 1 ≤ k ≤ 2n - 1).
Output
Print single integer — the integer at the k-th position in the obtained sequence.
Examples
input
3 2
output
2
input
4 8
output
4
Note
In the first sample the obtained sequence is [1, 2, 1, 3, 1, 2, 1]. The number on the second position is 2.
In the second sample the obtained sequence is [1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1]. The number on the eighth position is 4.
题意 :造一个序列,一开始只给一个元素1,按照规则操作,每次操作,将上一轮得到的序列放在最末端,并在上一轮的原序列后加上一个n值,形成一个新的序列,大体的结构是 (原序列–>n –> 原序列)。然后输入n表示有n-1次操作,输入k表示进行n-1次操作之后序列中的第k个元素是多少。n小于等于50。
题解:根据操作次数,可以得到序列的规律:
第0次 1
第1次 1 2 1
第2次 1 2 1 3 1 2 1
第4次 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1
第5次 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1 5 1 2 1 3 1 2 1 4 1 2 1 3 1 2 1
以此类推……..
可以发现,奇数位置上的k都是1。
并且,因为整个序列都是由1开始往后增加变化的,也就是说序列是固定的,不随操作次数的变化而改变第k位的值,n只决定了序列的长度。
然后,选择一个k值(偶数)时,将其一直×2,最后可以达到序列n长度的一半,此时序列n长度的一半,刚好是输入的n值。也就是说,n次操作序列的长度是2×n。
因此,从k×2一直到n的一半的次数,就是flag,用n值减去这个次数,即可得到第k位的数,当k值不是2的n次方中的值时,乘2过程中会超出而不等于n序列长度的一半,当超过后,对k取摸(相当于将超出的部分折回来,对应序列的前半部分位置),再继续×2,达到half的次数仍然可以用n值减去,而得到是第几次操作,对应序列的K值。
#include<stdio.h>///一开始给一个序列,只有一个元素1
#include<math.h>///然后每次做一个操作,将上一轮得到的序列放在最末端,在上一轮原本的序列后面加上一个n值
int main()
{
long long n,k;
while(scanf("%lld%lld",&n,&k)!=EOF)
{
if(k%2!=0)printf("1\n");
else
{
long long flag=0;
long long half=pow(2,n-1);
k=k%half;
while(k!=half&&k!=0)
{
k=k*2;
flag++;
if(k>half)k=k%half;
}
printf("%lld\n",n-flag);
}
}
}