CF949B A Leapfrog in the Array 思维题,推理

题意:

Dima是一名初级程序员。 在他的工作中,他经常不断地重复以下操作:从数组中删除每个第二个元素。 有一天,他对这个问题的解决方案感到厌倦,他提出了以下华丽的算法。

假设有一长度为2n的数组,最初的数组包含从1到n的n个数字,数字i位于序号为2i - 1的单元格中(序号从1开始编号),并且数组的其他单元格为空。每个步骤你需要选择一个最大序号的非空单元格,并将其中的数字移动到它左边最近的空单元格。一直循环该过程,直到所有n个数字出现在数组的前n个单元格中。例如,如果n = 4,则数组更改如下:

题解:
我们不难发现,每个数的初始位置都是基数,每个空格的位置都是偶数,所以没个数所能移动到的位置也只能是偶数。所以一旦一个数经过移动调到基数位,这一定就是这个数的最终位置。
考虑一个数被移动到位置 xx, 显然,xx 之前的所有数都是没有移动过的。而且 xx 之前的数的个数恰好为 x/2x/2,那么 xx 在移动之前的位置就是 x+(nx)/2x+(n-x)/2。所以我们就一直将 xx 调到下一个位置,直到 xx 的位置是基数即可。

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;
}
posted @ 2018-10-12 11:03  EM-LGH  阅读(167)  评论(0编辑  收藏  举报