sgu 153 Playing with matches

39 篇文章 0 订阅
20 篇文章 0 订阅
153. Playing with matches
time limit per test: 0.5 sec.
memory limit per test: 4096 KB
input: standard input
output: standard output



Little boy Petya plays a game with his friend. They have a heap that consists of N (1<=N<=10^9) matches. It is possible to take 1,P1,P2,...,Pm (2<=Pi<=9, 0<=m<=8) matches from the heap.
Players take matches from the heap one by one. The player who takes the last match looses. Petya proved that for any set of N and Pi one of players has winning strategy, i.e. set of rules driving to a victory independently of opponent's moves. You task is to discover who has this strategy.

Input
Input file consist of K test cases. Natural number K is written in the first line. Every test case describes one game: numbers N and M are written in first line of every test case, and second line contains sequence Pi. All numbers in then input are integer numbers. So, if K=2, then second and third lines describe first game and fourth and fifth lines describe second game.

Output
For each test case write in the output file phrase FIRST PLAYER MUST WIN if first player have winning strategy, and SECOND PLAYER MUST WIN therwise.

Sample test(s)

Input
1
5 3
2 3 5

Output
SECOND PLAYER MUST WIN

就是一个取石子游戏,目测是由周期的,但是我不知道周期是多少,试了几种瞎猜的都WA了,后来就愤怒地枚举可能的周期,结果就AC了。求大神给正解。

我的代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<set>
#include<algorithm>
#include<vector>
#include<cstdlib>

#define inf 0xfffffff
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define FOR(a,b) for(int a=1;a<=(b);(a)++)

using namespace std;
int const nMax = 2000;
int const base = 10;
typedef int LL;
typedef pair<LL,LL> pij;

//    std::ios::sync_with_stdio(false);

int n;
int p[10];
int m;
int k;
bool ok[nMax];

int gcd(int a,int b){
    return b==0?a:gcd(b,a%b);
}
int lcp(int a,int b){
    return a*b/gcd(a,b);
}

bool check(int l){
    for(int i=0;i<l;i++){
        for(int j=1;j<10;j++)if(ok[i]!=ok[i+j*l])return false;
    }
    return true;
}

int main(){
    scanf("%d",&k);
    while(k--){
        int d=1;
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++){
            scanf("%d",&p[i]);
        }
        FOR(i,nMax-1)ok[i]=false;
        ok[0]=true;
        for(int i=1;i<nMax;i++)if(!ok[i]){
            if(i+1<nMax)
            ok[i+1]=true;
            for(int j=0;j<m;j++)if(i+p[j]<nMax)
                ok[i+p[j]]=true;
        }
        int l;
        for(l=1;l<=50;l++){
            if(check(l))break;
        }
        if(!ok[n%l])printf("SECOND PLAYER MUST WIN\n");
        else      printf("FIRST PLAYER MUST WIN\n");
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值