hdu 1517 a multiplication game(簡單巴什博弈)
題意:
你和乙個人玩遊戲,給你乙個數字n,每次操作可以從2~9中任選乙個數字,並把它與p相乘,(遊戲開始時p=1)
兩人輪流操作,當乙個人操作完後p>=n,這個人就是勝者。
解題思路:
由於每次都是從p=1開始的,所以只要判斷每個遊戲中1為必敗點還是必勝點即可。(以下各式 / 均為取上整)
依照上面所提到的演算法,將終結位置,即[n,無窮]標記為必敗點;
然後將所有一步能到達此必敗段的點標記為必勝點,即[n/9,n-1]為必勝點;
然後將只能到達必勝點的點標記為必敗點,即[n/9/2,n/9-1]為必敗點;
重複上面2個步驟,直至可以確定1是必勝點還是必敗點。
**:
#include #include #include #include #include using namespace std;
typedef long long ll;
const int maxn = 1008;
int a[maxn], k, val[maxn];
void init()
}}int main()
}if (res == 1) printf("stan wins.\n");
else printf("ollie wins.\n");
}return 0;
}
hdu 2147 kiki's game(簡單)
題目大意:就是有乙個遊戲,在乙個n*m的矩陣中起始位置是(1,m),走到終止位置(n,1);遊戲規則是只能向左,向下,左下方向走,想走到終點的為獲勝者。
只要把pn狀態圖描繪出來就行了:
**:
#include #include #include #include #include using namespace std;
typedef long long ll;
int main()
return 0;
}
m堆石子,每堆有對應乙個(bi,ni),表示這堆有ni個石子,每次可以拿bi^x個石子(1<=bi^x<=ni),誰不能拿誰輸,1和2輪流拿,兩人足夠機智,問誰必勝
input
第一行一整數t表示用例組數,每組用例首先輸入石子堆數m,之後2*m個整數(bi,ni)來表示每堆石子
(1<=m<=100,1<=bi,ni<=1e9)
output
輸出必勝者
sample input3
1 2 3
1 7 3
2 6 11 3 2
sample output2
1 2
solution
組合遊戲,關鍵在於怎麼計算出每堆石子的sg值
b為奇數,那麼b^x必為奇數,根據奇偶性輕易得知當n為奇數時先手必勝(sg=1),當n為偶數時後手必勝(sg=0)
b為偶數,令n=x*(b+1)+t(0<=t<=b),那麼問題其實變成t個石子,每次可以拿1個或b個,由於t<=b,所以只有當t=b時先手有機會第一次拿b個,其他所有情況兩個人都無法拿b個,當t < b時,t為奇則先手勝(sg=1),t為偶則後手勝(sg=0),t=b時兩個後繼狀態分別是b-1和0,sg值分別是0和1,故t=b時sg=2
**:
#include#include#include#include#include#include#include#include#include#includeusing namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define maxn 1111
int main()
else
}printf("%d\n",ans?1:2);
}return 0;
}
hdu 1404 digital deletions
題意:給乙個長度不超過6字元的數字字串。兩種操作二選一:
1、把任意一位變成比他本身小的數字。比如205,可以把5變成0,1,2,3,4,成了200,201.so on。
2、把任意乙個0後及他本身去掉。比如205,去掉2和他後面的數字變成了2。
問最後去掉數字的算贏。問先手有木有必勝策略。
題解:可以通過sg函式的性質。暴力吧1-1e6每個數字的狀態求出來。能一步到達必敗狀態的都為必勝點。sg[1]明顯是必敗點,每次從必敗點去找。怎麼找?
1、可以將每位上的數字+1,直到等於9.
2、如果位數小於6,可在末尾+0.再加上若干數。最後只要知道sg值是0或者1就ok了。
**:
//#include#include #include #include #include #include #include using namespace std;
typedef long long ll;
const int maxn = 1000000;
int sg[maxn], ff[6] = ;
int getlen(int m)
void dfs(int m)
}int k = m, l = 1;
while(q < 6)
}int main()
char cc[8];
while(~scanf("%s", cc))
int ccl = strlen(cc);
int m = 0;
for(int i = 0; i < ccl; i++)
m = m*10+cc[i]-'0';
if (sg[m]) puts("yes");
else puts("no");
}return 0;
}
hdu 1760 a new tetris game + hdu 1809 a new tetris game(2)
第乙個可以暴力, 第二個是多組的就求一下sg值;
這題就是狀態不好儲存;我用的是map+vector的組合存的;(這題直接用map更方便)
第乙個不存狀態也可以過;
**:hdu1760
//#include#include #include #include #include #include #include #include #include using namespace std;
typedef long long ll;
const int maxn = 52;
map, int> dp;
int n, m;
int dfs(vectormat)
mat.push_back(tmp);
}int res = dfs(mat);
if (res) puts("yes");
else puts("no");
}return 0;
}
**: hdu1809 **沒太大的區別;
//#include#include #include #include #include #include #include #include #include using namespace std;
typedef long long ll;
const int maxn = 52;
map, int> dp;
int n, m;
int dfs(vectormat) ;
if (dp.count(mat)) return dp[mat];
int res = 0;
for(int i = 0; i < n-1; i++)
mat.push_back(tmp);
}res ^= dfs(mat);
}if (res) puts("yes");
else puts("no");
}return 0;
}
Ubuntu的一些常用終端命令 不定時更新
ubuntu中檢視已安裝軟體包的方法 如果想把這些包的資訊複製到一檔案裡,可用下面的方法.方法二 在終端輸入 sudo dpkg l 然後在終端的介面裡複製列出來的資訊就可以了 終端檢視時,一定要做如下步驟 點終端介面上的 編輯 配置檔案首選項 滾動 回滾 不限制 打上勾 這樣輸入到介面的資訊就完整...
一些博弈題
題目鏈結 題面較長,這裡不貼圖了 一道比較基礎的博弈題,關鍵在於,如果起始點距離與0邊相連點之間存在奇數條邊時則先手存在必勝策略,反之則先手必敗。include include include include include include include include include inclu...
Linux一些常見操作命令(不定時更新)
1.使用ls命令瀏覽檔案根目錄,在tmp目錄下建立乙個臨時目錄,比如file temp 2.瀏覽 usr目錄下所有檔案列表,包含隱含檔案以及檔案詳細許可權資訊,區分檔案和目錄的區別。3.用pwd命令顯示當前工作目錄 4.使用命令將 i love os 寫到file1.txt檔案裡,然後使用命令讀出檔...