Topic links
Test instructions
A and b take turns in constructing a word, adding one character at a time, asking for the prefix of a given n string, the person who cannot add the character loses the game, and the person who loses is the first round of the game. Ask a initiator, after the K-wheel game, the last person who wins.
Ideas:
It is very obvious that n strings are inserted into the dictionary tree first, because there is a fork in the dictionary tree, it is not possible to judge the string length parity only. The dictionary tree is considered as a non-ring state diagram, and if sorted in reverse order by topological sort, its successors are judged when each node is judged. Define two arrays Can_win[u], can_lose[u], means u node go down "may win?" "and the U-node go down" may lose? , then take the opposite is to win and will be defeated, "may win" <-opponent next impossible to win, "may lose" <-opponent next cannot lose.
Code:
#include <bits/stdc++.h>const int N = 1e5 + 5;char str[n];int ch[n][26];int sz;bool can_win[n], can_lose[n];void INI T () {memset (ch[0], 0, sizeof (ch[0])); SZ = 1;} void Insert (char *s) {int u = 0, C; for (int i=0; s[i]; ++i) {c = s[i]-' a '; if (!ch[u][c]) {memset (Ch[sz], 0, sizeof (Ch[sz])); CH[U][C] = sz++; } u = Ch[u][c]; }}void DFS (int u) {can_win[u] = can_lose[u] = false; bool Is_leaf = true; for (int c=0; c<26; ++c) {int v = ch[u][c]; if (v) {is_leaf = false; DFS (v); Can_win[u] |=!can_win[v]; Can_lose[u] |=!can_lose[v]; }} if (Is_leaf) {Can_lose[u] = true; }}int Main () {int n, K; scanf ("%d%d", &n, &k); Init (); for (int i=0; i<n; ++i) {scanf ("%s", str); Insert (str); } DFS (0); if (!can_win[0]) {puts ("Second"); of course! } else if (can_lOse[0]) {puts ("first"); Can lose && can win, control! } else {//can win &&!can lose, change A and B every turn! printf ("%s\n", (K & 1)? "First": "Second"); } return 0; }
Dictionary tree + game CF 455B A lot of games (solitaire game)