题意:

现在给你一个n,表示有2*n-1个方格,第奇数方格上会有一个数字 1-n按顺序放。第偶数个方格上是没有数字的。变动规则是排在最后一个位置的数字,移动到它前边最近的空位 。 直到数字之间没有空位。之后有q次询问。每次问你这个位置上的数是多少

题解:

 1:  1
 2:  1 2
 3:  1 3 2
 4:  1 3 2 4
 5:  1 5 2 4 3
 6:  1 4 2 6 3 5
 7:  1 6 2 5 3 7 4
 8:  1 5 2 7 3 6 4 8
 9:  1 9 2 6 3 8 4 7 5
10:  1 6 2 10 3 7 4 9 5 8
11:  1 9 2 7 3 11 4 8 5 10 6
12:  1 7 2 10 3 8 4 12 5 9 6 11
13:  1 12 2 8 3 11 4 9 5 13 6 10 7
14:  1 8 2 13 3 9 4 12 5 10 6 14 7 11
15:  1 12 2 9 3 14 4 10 5 13 6 11 7 15 8
16:  1 9 2 13 3 10 4 15 5 11 6 14 7 12 8 16
17:  1 17 2 10 3 14 4 11 5 16 6 12 7 15 8 13 9
规律一、每一行第一个数都是1
规律二、每一行奇数位置(设这个奇数位置为x)的数,都是确定的大小的。它的值就是2*x-1
规律三、每一行从第三个数开始到这一行倒数第二个数(闭区间,设为[a3,a4....a(n-1)]),对应着上一行的
        [a1+1,a2+1....a(n-3)+1]
规律四、每一行第二个数是上一行的最后一个数加1

1、如果题目询问的位置是奇数,就直接打印出2*x-1

2、如果题目询问的位置偶数(设这个位置为x),那就让这个位置减去2(如果这个位置是2,那就把x变成上一行末尾那个位置),在对应的上一行找结果。一直向上一行移动。直到x变成奇数

代码:

 1 #include<cstdio>
 2
 3 #include<cstring>
 4
 5 #define LL long long
 6
 7 using namespace std;
 8
 9 int main()
10
11 {
12
13     int p;
14
15     LL n,m,a;
16
17     scanf("%lld%d",&n,&p);
18
19     while(p--)
20
21     {
22
23         scanf("%lld",&a);
24
25         if(a%2==1)
26
27         {
28
29             printf("%lld\n",a/2+1);
30
31             continue;
32
33         }
34
35         m=n;
36
37         while(a%2==0)
38
39         {
40
41             a=m-a/2;
42
43             m=a;
44
45         }
46
47         printf("%lld\n",n-a+(a+1)/2);
48
49     }
50
51 }
12-16 20:05