码迷,mamicode.com
首页 > 其他好文 > 详细

[SDOI2016]硬币游戏

时间:2018-06-27 17:31:21      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:close   题解   次方   scanf   百度一下   str   namespace   http   cstring   

这道题不难吧,为什么大佬们没有题解呢,一定是dalao们觉得太简单了吧,弄得我好几天才做出来。。。

很显然,直接按题意模拟即可,求出sg函数,异或和就好了,不知道sg函数的可以自己百度一下。。。非常神奇的网站

不知道为什么,大佬们都是每次输入n之后再算的sg函数,并且每次算的时候都用的是2的多少次方乘3的多少次方,明明直接求更简单的,效率也并不低。。。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int Maxn=31000;
const int Maxm=2100;

int sg[Maxn][31];
int s[Maxm];

int n,m,c,t,ans;

void getsg() {
    for(int i=1;i<=30000;i++) {
        int temp=i;
        int san=0,er=0;
        while(temp%2==0) temp/=2,er++;
        while(temp%3==0) temp/=3,san++;
        for(int q=1;q<=20;q++) {
            for(int k=1;k<=q;k++) {
                for(int p=1,tempp=2;p*k<=er;p++,tempp*=2) {
                    int ans=0;
                    for(int j=1,temp2=tempp;j<=k;j++,temp2*=tempp)
                        ans^=sg[i/temp2][q];
                    s[ans]=1;
                }
                for(int p=1,tempp=3;p*k<=san;p++,tempp*=3) {
                    int ans=0;
                    for(int j=1,temp3=tempp;j<=k;j++,temp3*=tempp)
                        ans^=sg[i/temp3][q];
                    s[ans]=1;
                }
            }
            while(s[sg[i][q]]) sg[i][q]++;
            for(int k=1;k<=q;k++) {
                for(int p=1,tempp=2;p*k<=er;p++,tempp*=2) {
                    int ans=0;
                    for(int j=1,temp2=tempp;j<=k;j++,temp2*=tempp)
                        ans^=sg[i/temp2][q];
                    s[ans]=0;
                }
                for(int p=1,tempp=3;p*k<=san;p++,tempp*=3) {
                    int ans=0;
                    for(int j=1,temp3=tempp;j<=k;j++,temp3*=tempp)
                        ans^=sg[i/temp3][q];
                    s[ans]=0;
                }
            }
        }
    }
}

int main() {
//  freopen("test.in","r",stdin);
    getsg();
    scanf("%d",&t);
    while(t--) {
        ans=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) {
            scanf("%d",&c);
            if(c==0) ans^=sg[i][m];
        }
        if(ans==0) puts("lose");
        else puts("win");
    }
//  fclose(stdin);
    return 0;
}

[SDOI2016]硬币游戏

标签:close   题解   次方   scanf   百度一下   str   namespace   http   cstring   

原文地址:https://www.cnblogs.com/shanxieng/p/9234862.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!