题意:
现在给你一个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 }