codeforces1033C Permutation Game

After a long day, Alice and Bob decided to play a little game. The game board consists of n cells in a straight line, numbered from 1 to n, where each cell contains a number ai between 1 and n. Furthermore, no two cells contain the same number.

A token is placed in one of the cells. They take alternating turns of moving the token around the board, with Alice moving first. The current player can move from cell i
to cell j only if the following two conditions are satisfied:

  1. the number in the new cell j
    must be strictly larger than the number in the old cell i (i.e. aj>ai
    )
  2. the distance that the token travels during this turn must be a multiple of the number in the old cell (i.e. |i−j|modai=0 ).

Whoever is unable to make a move, loses. For each possible starting position, determine who wins if they both play optimally. It can be shown that the game is always finite, i.e. there always is a winning strategy for one of the players.

Input

The first line contains a single integer n(1≤n≤105) — the number of numbers.

The second line contains n integers a1,a2,…,an (1≤ai≤n). Furthermore, there are no pair of indices i≠j such that ai=aj

.
Output

Print s — a string of n characters, where the i-th character represents the outcome of the game if the token is initially placed in the cell i. If Alice wins, then si has to be equal to “A”; otherwise, si has to be equal to “B”.


基本博弈论题目。根据题意,在数组中建立路径,尤其限定条件可知,可行的路径有限且小于 n2 ,因此建立邻接表存储可行路径。本题中容易确定其必败态,在数组中不能再移动的点,即邻接表为空的节点。
现在从位置 i 上开始移动,考虑在位置i上落子的输赢

  1. 存在一种方案可移动到必败
    也就是说,在当前移动完成后,下一轮开始的位置一定会失败,那么对于当前这一轮来说,这一局必胜。
  2. 任何移动方式都不能达到必败态
    无论如何移动,下一轮开始的位置都一定会赢,那么对于这一轮来说,这一局必败
    根据以上的递推方式,就可以推得所有位置上的输赢。

#include <stdio.h>
#include <climits>
#include <algorithm>
#include <map>
using namespace std;
struct ListNode{
    int index;
    ListNode* pre;
    ListNode(){}
    ListNode(int i):index(i),pre(NULL){}
};
struct Head{
    ListNode* p;
    Head():p(NULL){}
};
inline int abs(int x){
    if(x<0)
        return -x;
    return x;
}

int len;
int board[100240];
Head adj[100240];
map<int,bool> mapping;
bool sol(int finish);//finish : index
int main(){
    scanf("%d",&len);
    for(int i=1;i<=len;i++)
        scanf("%d",&board[i]);
    for(int i=1;i<=len;i++){
        for(int j=i+board[i];j<=len;j+=board[i])
            if(board[i]<board[j]){
                ListNode *edge=new ListNode(j);
                edge->pre=adj[i].p;
                adj[i].p=edge;
            }
        for(int j=i-board[i];j>0;j-=board[i])
            if(board[i]<board[j]){
                ListNode *edge=new ListNode(j);
            edge->pre=adj[i].p;
            adj[i].p=edge;

            }
    }
    for(int i=1;i<=len;i++)
        if(sol(i))
            printf("A");
        else
            printf("B");
    printf("\n");
    return 0;
}
bool sol(int finish){
    if(mapping.find(finish)!=mapping.end())
        return mapping[finish];
    ListNode* next=adj[finish].p;
    bool ans=false;
    while(next){
        ans |= !sol(next->index);
        next=next->pre;
    }
    mapping[finish]=ans;
    return ans;
}

猜你喜欢

转载自blog.csdn.net/white_156/article/details/83514258