51nod 1490 多重游戏

2 篇文章 0 订阅
2 篇文章 0 订阅

题目链接

分析:
这道题很有意思啊。一开始我一直想找规律什么的,但并找不到。
后来发现自己naive了,不光一局之中不能找到规律,K局也会影响到最后的结果。如果先手拥有主动权,可以控制自己的输赢,让自己一直输,最后一局再赢。
于是题目变成了建一颗字典树,然后遍历一遍,找找是否有先手必胜或必败态。再考虑。

代码:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <set>
#include <map>
#include <vector>

using namespace std;

const int maxn = 1e5 + 5;

int ch[maxn][30];
int sz = 1;

void trie_insert(char *s) {
    long len = strlen(s);
    int u = 0;
    for (int i = 0; i < len; i ++) {
        int c = s[i] - 'a';
        if (!ch[u][c]) {
            memset(ch[sz], 0, sizeof(ch[sz]));
            ch[u][c] = sz ++;
        }
        u = ch[u][c];
    }
}

bool win(int u) {
    int f = 0, s = 0;
    for (int c = 0; c < 26; c ++) {
        int v = ch[u][c];
        if (!v) continue;
        if (win(v)) s ++;
        else f ++;
    }
    if (f) return true;
    return false;
}

bool lose(int u) {
    int f = 0, s = 0;
    for (int c = 0; c < 26; c ++) {
        int v = ch[u][c];
        if (!v) continue;
        if (lose(v)) s ++;
        else f ++;
    }
    if (!s && !f) return true;
    if (f) return true;
    return false;
}

int main(int argc, char const *argv[]) {
    int N, K;
    cin>>N>>K;
    memset(ch[0], 0, sizeof(ch[0]));
    for (int i = 0; i < N; i ++) {
        char s[maxn];
        scanf("%s", s);
        trie_insert(s);
    }

    bool first_win = win(0);
    bool first_lose = lose(0);

    if (first_win && first_lose) puts("First");
    else {
        if (first_lose) puts("Second");
        else if (first_win) {
            if (K % 2) puts("First");
            else puts("Second");
        }
        else puts("Second");
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值