程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> UVA 11249 - Game(博弈)

UVA 11249 - Game(博弈)

編輯:C++入門知識

UVA 11249 - Game(博弈)


UVA 11249 - Game

題目鏈接

題意:兩堆石頭,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;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved