ECNU OJ 3354 領外賣(博弈-SG函式)

kewlgrl發表於2018-03-23

3354. 領外賣

Time limit per test: 2.0 seconds

Memory limit: 256 megabytes

林吉吉(LJJ)和金大哥(JDG)為了誰去領外賣吵得不可開交,為了確定誰去領外賣,李蓓蓓學姐設計了一個簡單的遊戲:給定一堆 n 個石子,每個人輪流從石子堆取走若干個石子,要求每次取走的石子數為正完全平方數(即此數為某個正整數的平方),拿走最後一顆石子的人獲勝,林吉吉先手。

請問若雙方都以最佳方式進行選擇,誰將去領外賣?

Input

第一行為資料組數 T

每組資料的第一行為 n 即石子的數目

資料約束:
對於 50%的資料保證 n30 
對於所有資料保證 T10001n105

Output

每組資料,若林吉吉贏了就輸出 JDG will get takeaways! 否則輸出 LJJ will get takeaways!

Examples

input
3
1
2
3
output
JDG will get takeaways!
LJJ will get takeaways!
JDG will get takeaways!

HDU1847稍微改了改能拿的石子的限制數目情況就AC了。

HDU1847傳送門:https://blog.csdn.net/mikasa3/article/details/51366553

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 100010
int sg[MAXN],f[MAXN],temp[MAXN];
void solve()
{
    int i,j,cnt=MAXN;
    f[0]=1;
    for(i=0; i<MAXN; i++) //f表示所有能取到的石子數的值
        f[i]=i*i;
    memset(sg,-1,sizeof(sg));
    sg[0]=0;
    for(i=1; i<=MAXN; i++) //求sg值,i表示石子數
    {
        memset(temp,-1,sizeof(temp));
        for(j=0; j<=cnt&&f[j]<=i; ++j)
            temp[sg[i-f[j]]]=0;//i-f[j]表示從i張石子中取走f[j]個後的狀態
        for(j=0;; ++j)
            if(temp[j]==-1)
            {
                sg[i]=j;
                break;
            }
    }
}
int main()
{
#ifdef ONLINE_JUDGE
#else
    freopen("F:/cb/read.txt","r",stdin);
//freopen("F:/cb/out.txt","w",stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin>>t;
    solve();
    while(t--)
    {
        int n;
        cin>>n;
        if(sg[n]) cout<<"JDG will get takeaways!"<<endl;//必敗點
        else cout<<"LJJ will get takeaways!"<<endl;
    }
    return 0 ;
}

相關文章