題目鏈接
題意:兩堆石頭,a和b,每次能取一堆任意數量,或者兩堆同時取,但是絕對值差不能超過k,最後不能取的人輸,問先手是否能贏
思路:先假設(a, b)石子,a是少的一堆,首先很容易看出(1, k + 2)是必敗的,設下一個是(2, x)那麼如果這個狀態能到(1, k + 2)那麼就是必勝,要找出(2, x)必敗狀態,就必然是上個狀態多的一堆石子 + k + 2 - 1,這樣無論怎麼取,都無法變成(1, k + 2),而後手由於先手取掉了一個,就可以了,因此可以這樣一個個去預處理出10W的必敗狀態,然後每次詢問直接判斷即可
代碼:
#include#include #include using namespace std; const int N = 100005; int t, k, q, a, b; int lose[N]; void init(int k) { memset(lose, 0, sizeof(lose)); lose[1] = 1 + k + 1; lose[1 + k + 1] = 1; int pre = 1; for (int i = 2; i <= 100000; i++) { if (lose[i]) continue; int tmp = lose[pre] + i - pre + k + 1; if (tmp > 100000) break; pre = i; lose[i] = tmp; lose[tmp] = i; } } int main() { scanf("%d", &t); while (t--) { scanf("%d%d", &k, &q); init(k); while (q--) { scanf("%d%d", &a, &b); if (a > b) swap(a, b); if (lose[a] == b) printf("LOSING\n"); else printf("WINNING\n"); } printf("\n"); } return 0; }