1. 程式人生 > >Codeforces 950D A Leapfrog in the Array ( 思維 && 模擬 )

Codeforces 950D A Leapfrog in the Array ( 思維 && 模擬 )

F12 sof hide 每一個 display ID RR closed 否則

題意 : 給出 N 表示有標號 1~N 的 N 個數,然後從下標 1 開始將這 N 個數每隔一位放置一個,直到 N 個數被安排完,現在有一個操作就是每次將數列中最右邊的數向離其左邊最近的空缺處填上,一直這樣子填,直到下標 1~N 被填滿,然後現在給出 Q 個詢問,每個詢問給出一個 X ,你需要回答下標為 X 的位置填放了什麽數?

分析 :

初始狀態每個數都處於奇數位,且可以根據位置下標得到具體的數是什麽,即 num = (pos>>1) + 1

觀察到當最後填充操作完成時,每個奇數位置的數是沒有移動過所以其值是確定的

即 num = (pos>>1) + 1 ( pos%2 != 0 )

後面就是要處理偶數位置的情況,按照題意從初始到最後去模擬貌似並不好做

考慮從最終狀態推回初始狀態,對於每一個偶數位的數

舉個例子 N = 4、考慮 1_243 時候的狀態

在 3 下一步就移動到 _ 這個偶數位的時候,它左邊是有 pos/2 個數的(奇數位置的數)

所以可以根據這個推出 3 移動到 _ 之後,它右邊應有 N - (pos>>1) - 1 個數

所以如果是從 1324 逆推回 1_243 的時候 _ 這個偶數位置對應的值應當是 N - (pos>>1)

如果經過 N - (pos>>1) 這個移動後,位置處於奇數位,那麽數就可以確定了

否則就繼續移動,最後就能對於每一個偶數位采取逆推的方式來得到其值

技術分享圖片
#include<bits/stdc++.h>
#define LL long long
using namespace std;

int main(void)
{
    long long N, Q;
    scanf("%I64d %I64d", &N, &Q);
    while(Q--){
        long long X;
        scanf("%I64d", &X);
        while(!(X&1))
            X += (N - (X>>1));
        printf(
"%I64d\n", (X>>1)+1); } return 0; }
View Code

Codeforces 950D A Leapfrog in the Array ( 思維 && 模擬 )