1. 程式人生 > >每天一道博弈論之“牛的數字遊戲”

每天一道博弈論之“牛的數字遊戲”

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;
const
int 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 ; }
View Code

錯誤原因:一開始沒有看到只能減去最大最小數碼T_T

每天一道博弈論之“牛的數字遊戲”