c++移棋子游戏

移棋子游戏

描述

给定一个有N个节点的有向无环图,图中某些节点上有棋子,两名玩家交替移动棋子。

玩家每一步可将任意一颗棋子沿一条有向边移动到另一个点,无法移动者输掉游戏。

对于给定的图和棋子初始位置,双方都会采取最优的行动,询问先手必胜还是先手必败。

输入

第一行,三个整数N,M,K,N表示图中节点总数,M表示图中边的条数,K表示棋子的个数。

接下来M行,每行两个整数X,Y表示有一条边从X出发指向Y。

接下来一行,K个空格间隔的整数,表示初始时,棋子所在的节点编号。

输出

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

输入样例 1 

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

输出样例 1

win

提示

数据范围与提示:

对于全部数据,N≤2000,M≤6000,1≤K≤N。

#include <iostream>
#include <vector>
#include <cstring>

using namespace std;

const int MAXN = 2005;

vector<int> graph[MAXN];
int sg[MAXN];
bool visited[MAXN];

int calcSG(int node) {
    if (visited[node]) return sg[node];
    visited[node] = true;

    vector<bool> mex(MAXN, false);
    for (int next : graph[node]) {
        mex[calcSG(next)] = true;
    }

    for (int i = 0; ; ++i) {
        if (!mex[i]) {
            sg[node] = i;
            break;
        }
    }
    return sg[node];
}

int main() {
    int N, M, K;
    cin >> N >> M >> K;

    memset(sg, -1, sizeof(sg));
    memset(visited, 0, sizeof(visited));

    int x, y;
    for (int i = 0; i < M; ++i) {
        cin >> x >> y;
        graph[x].push_back(y);
    }

    int totalSG = 0;
    for (int i = 0; i < K; ++i) {
        cin >> x;
        totalSG ^= calcSG(x);
    }

    if (totalSG != 0) {
        cout << "win" << endl;
    } else {
        cout << "lose" << endl;
    }

    return 0;
}

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值