牛牛和牛可樂的賭約2
阿新 • • 發佈:2021-01-14
技術標籤:補題
連結: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;
}