首页 > 其他 > 详细

移棋子游戏

时间:2020-07-22 23:37:05      阅读:88      评论:0      收藏:0      [点我收藏+]

题目描述 

给定一个有N个节点的有向无环图,图中某些节点上有棋子,两名玩家交替移动棋子。
玩家每一步可将任意一颗棋子沿一条有向边移动到另一个点,无法移动者输掉游戏。
对于给定的图和棋子初始位置,双方都会采取最优的行动,询问先手必胜还是先手必败。

输入描述:

第一行,三个整数N,M,K,N表示图中节点总数,M表示图中边的条数,K表示棋子的个数。
接下来M行,每行两个整数X,Y表示有一条边从X出发指向Y。
接下来一行,K个空格间隔的整数,表示初始时,棋子所在的节点编号。

输出描述:

若先手胜,输出win,否则输出lose。

输入

6 8 4
2 1
2 4
1 4
1 5
4 5
1 3
3 5
3 6
1 2 4 6

输出

win

备注:

对于全部数据,N \leq 2000,M \leq 6000,1 \leq K \leq NN2000,M6000,1KN。
// SG函数模板题
#include<bits/stdc++.h>
using namespace std;
const int MAXM = 1e4 + 7;
const int MAXN = 2e3 + 7;
int head[MAXM], ver[MAXM], nex[MAXM], vis[MAXM], sg[MAXM], tot;
int N, M, K;
void add(int x, int y) {
    ver[++tot] = y; nex[tot] = head[x]; head[x] = tot;
}
void dfs(int x) {
    if (vis[x]) return;
    vis[x] = 1;
    int up = 0;
    int mark[MAXN] = {0};
    for (int i = head[x]; i; i = nex[i]) {
        dfs(ver[i]);
        up = max(up, sg[ver[i]]);
        mark[sg[ver[i]]] = 1;
    }
    for (int i = 0; i <= up + 1; i++) {
        if (!mark[i]) {
            sg[x] = i; break;
        }
    }
}
void getSG() {
    for (int i = 1; i <= N; i++) {
        if (!vis[i]) dfs(i);
    }
}
int main() {
    int x, y;
    cin >> N >> M >> K;
    for (int i = 1; i <= M; i++) {
        cin >> x >> y;
        add(x, y);
    }
    getSG();
    int ans = 0;
    for (int i = 1; i <= K; i++) {
        cin >> x;
        ans ^= sg[x];
    }
    if (ans) cout << "win" << endl;
    else cout << "lose" << endl;
    return 0;
}

移棋子游戏

原文:https://www.cnblogs.com/HighLights/p/13363443.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!