Lyft Level 5 Challenge 2018 C. Permutation Game(博弈)

題目鏈接

                                              C. Permutation Game

題意:

兩人輪流移動鋼珠,誰最先不能移動就爲敗,移動規則:a_i>a_j 且 |i-j|~mod~a[j]=0

題解:

若當前點的後繼點都爲必勝點,那此點爲必敗點,反之爲必勝點                                              — 博弈論

觀察當前點能到達的點的狀態就能判斷當前點的狀態,因爲一個點的後繼點必須滿足a_i>a_j ,所以要先從權值大的點開始標記狀態

代碼:

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 2e5+55;
int arr[MAXN];  // 記錄每個位置的權值 
int pos[MAXN];  // 標記權值的位置
int dp[MAXN];   // 標記每個位置的狀態
int main()
{
    int n,val;
    cin>>n;
    for(int i=1;i<=n;++i)
    {
        cin>>arr[i];
        pos[arr[i]] = i;
    }
    for(int i = n;i>=1;--i)       //權值從大到小
    {
        for(int j=pos[i]+ i;j<=n;j += i) //位置向後移動權值的整數倍
        {
            if(arr[j]>i && dp[j]==2)  //有一個點爲必敗點,此點就爲必勝點
            {
                dp[pos[i]] = 1;
                break;
            }
        }
        for(int j=pos[i]-i;j>=1;j -= i) //向前移動
        {
            if(arr[j]>i && dp[j]==2)
            {
                dp[pos[i]] = 1;
                break;
            }
        }
        if(dp[pos[i]] != 1)       //後繼點都爲必勝點
           dp[pos[i]] = 2;
    }
    for(int i=1;i<=n;++i)
    {
        if(dp[i]==1) cout<<'A';
        else cout<<'B';
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章