1. 程式人生 > 其它 >牛牛和牛可樂的賭約2

牛牛和牛可樂的賭約2

技術標籤:補題

連結:https://ac.nowcoder.com/acm/contest/11334/B
來源:牛客網

題目描述 
牛牛感覺在上一次賭約中,情況對於自己非常不利,所以決定再賭一場。
這時候,牛蜓隊長出現了:第一,絕對不意氣用事;第二,絕對不漏判任何一件壞事;第三,絕對裁判的公正漂亮。
牛蜓隊長帶他們來到了一個棋盤遊戲,棋盤左上角是(0,0)(0,0),這個棋盤在(x,y)(x,y)的位置有一個棋子,牛牛和牛可樂輪流移動這個棋子,這個棋子可以左移也可以上移,可以移動一格或者兩格,直到不能再移動(即到(0,0)(0,0))的那個人算輸。
如果原本在(x,y)(x,y),左移一格即為(x,y -1)(x,y−1),上移一格即為(x-1,y)(x−1,y)
這個時候,牛牛為了彌補上一局的不公平,決定要自己先手,如果兩個人都用最優的策略,最後牛牛是否能獲勝。


輸入描述:
有多組輸入樣例,第一行為樣例組數t(t\leq 1×10^6)t(t≤1×10 
6
 )
接下來 tt 行每行有一個整數 xx 和 yy,分別表示初始位置(x,y\leq 1×10^9)(x,y≤1×10 
9
 )
輸出描述:
輸出t行,如果牛牛獲勝,就輸出”yyds”(不帶引號)

否則輸出”awsl”

示例1
輸入
複製
2
0 0
0 2
輸出
複製
awsl
yyds

首先這道題資料這麼大,一般情況一定是找規律的,而找規律的·題目我們打表是最快有效的方法,所以我先寫了一個暴力程式

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <unordered_set>
#include <map>

using namespace std;

#define int long long 

map<int, int> f;

int sg(int
x){ if (f[x]) return f[x]; unordered_set<int> S; for (int i = 1; i <= 2; i ++){ if (x > i) S.insert(sg(x - i)); } for (int i = 0; ; i ++){ if (!S.count(i)) return f[x] = i; } } signed main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int T; scanf("%d"
, &T); //memset(f, -1, sizeof f); while(T --){ int x, y; cin >> x >> y; int res = sg(x) ^ sg(y); if (res) cout << "yyds" << endl; else cout << "awsl" << endl; } return 0; }

一般是先手必勝的概率是大於後手的
通過我反覆無常的嘗試,我發現如果x和y的差的絕對值是3的倍數的話,那麼此時是必敗的,否則是必勝的,所以此時程式碼是

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

signed main(){
	int T;
	scanf("%d", &T);
	
	while(T --){
		int x, y;
		scanf("%d%d", &x, &y);
		if (abs(x - y) % 3 == 0)   cout << "awsl" << endl;
		else  cout << "yyds" << endl;
	}
	
	return 0;
}