CF949B A Leapfrog in the Array 思维题,推理
题意:
Dima是一名初级程序员。 在他的工作中,他经常不断地重复以下操作:从数组中删除每个第二个元素。 有一天,他对这个问题的解决方案感到厌倦,他提出了以下华丽的算法。
假设有一长度为2n的数组,最初的数组包含从1到n的n个数字,数字i位于序号为2i - 1的单元格中(序号从1开始编号),并且数组的其他单元格为空。每个步骤你需要选择一个最大序号的非空单元格,并将其中的数字移动到它左边最近的空单元格。一直循环该过程,直到所有n个数字出现在数组的前n个单元格中。例如,如果n = 4,则数组更改如下:
题解:
我们不难发现,每个数的初始位置都是基数,每个空格的位置都是偶数,所以没个数所能移动到的位置也只能是偶数。所以一旦一个数经过移动调到基数位,这一定就是这个数的最终位置。
考虑一个数被移动到位置 , 显然, 之前的所有数都是没有移动过的。而且 之前的数的个数恰好为 ,那么 在移动之前的位置就是 。所以我们就一直将 调到下一个位置,直到 的位置是基数即可。
Code:
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
long long n;
int q;
cin >> n >> q;
while(q--)
{
long long x;
cin >> x;
while(1)
{
if(x % 2 == 1) break;
x = x + (n - x / 2);
}
cout << (x - 1) / 2 + 1 << endl;
}
return 0;
}