每天一道博弈論之“牛的數字遊戲”
阿新 • • 發佈:2018-03-06
getch AC cli fcc 最小數 ont close 一個數 bool
題意:
給你一個數n(n<=1e6),玩家可以進行的操作為減去該數最大數碼或最小非零數碼。即數2014可以減去1變成2013或減去4變成2010。將數變成0的一方贏。
題解:
直接求出1-1e6的SG函數值即可。復雜度O(n*lgn)(這裏的log以10為底)。
#include<iostream> #include<cstdio> #include<cstring> #define LL long long #define RI register int using namespace std; constView Codeint INF = 0x7ffffff ; const int N = 1e6 + 10 ; inline int read() { int k = 0 , f = 1 ; char c = getchar() ; for( ; !isdigit(c) ; c = getchar()) if(c == ‘-‘) f = -1 ; for( ; isdigit(c) ; c = getchar()) k = k*10 + c-‘0‘ ; return k*f ; } int sg[N] ; int ser(int x) {if(sg[x]) return sg[x] ; bool v[100] = {0} ; int ii = x, y, minn = INF, maxx = -INF ; while(ii) { y = ii%10 ; ii /= 10 ; if(y) minn = minn < y ? minn : y ; maxx = maxx > y ? maxx : y ; } v[sg[x-minn]] = 1 ; v[sg[x-maxx]] = 1 ; for(int i=0;;i++)if(!v[i]) { sg[x] = i ; return i ; } } int main() { int t = read() ; sg[0] = 0 ; for(int i=1;i<=1000000;i++) sg[i] = ser(i) ; while(t--) { int x = read() ; if(sg[x]) printf("YES\n") ; else printf("NO\n") ; } return 0 ; }
錯誤原因:一開始沒有看到只能減去最大最小數碼T_T
每天一道博弈論之“牛的數字遊戲”