HDU 2240(状态标记)

题目大意:

      给定一个飞行棋的棋牌(最大200),Lele和Yueyue两人下分别丢骰子.每个人丢出的点数依次为f0=(a*c+b)%6+1,f1=(a*f0+b)%6+1.....以此类推.Lele先走,问谁会赢,或者没人能赢.

分析:

       一共就200个格子,点数为1-6,2人下,总的状态数为200*200*2*6.当一个状态被访问过后再次被访问到,则说明发生循环,这局无人能赢. 比较坑的是这题飞的时候会出现循环,即:N N2 N1 N... ,1飞到2,2飞到1无限循环.解决方法很简单,只要判断循环次数是否超过格子个数就好了,没必要写判环.

解题代码如下,代码写的很烂,凑合着看吧:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#include <list>
#include <queue>
#include <map>

using namespace std;
#define INF 0x3f3f3f3f;
int vis[205][205][8][2];
int gap[205];
int  Lele,Yueyue;
int main() {
    int n,a,b,c;
    while (~scanf("%d%d%d%d", &n, &a,&b,&c)) {
        Lele=Yueyue=0;
        memset(vis,0,sizeof(vis));
        for(int i=0;i<n;i++)
            gap[i]=-1;
        char s[6];
        for(int i=0;i<n;i++) {
            scanf("%s",s);
            if(s[0]=='G'){
                int sum=0;
                for(int j=1;j<strlen(s);j++){
                    sum=s[j]-'0'+sum*10;
                }
                gap[i]=sum;
            }
        }
        a=a%6;
        b=b%6;
        c=c%6;
        int f=c,num;
        int end=n-1;
        vis[0][0][f][0]=1;
        while(true){
            num=(a*f+b)%6+1;
            f=num;
           // printf("%d",num);
            Lele+=num;
            if(Lele>end){
                Lele=end-(Lele-end);
            }
            int cnt=0;
            bool flag=true;
            while(gap[Lele]!=-1){
                if(cnt>n){
                    flag=false;
                    break;
                }
                cnt++;
                Lele=gap[Lele];
            }
            if(!flag){
                printf("Impossible\n");
                break;
            }
            if(Lele==end){
                printf("Lele\n");
                break;
            }
            if(Lele==Yueyue)
                Yueyue=0;
            if(vis[Lele][Yueyue][num][0]){
               // printf("32\n");
               printf("Impossible\n");
                break;
            }
            vis[Lele][Yueyue][num][0]=1;
          //  printf("l:%d %d\n",Lele,num);
            num=(a*f+b)%6+1;
            f=num;
            Yueyue+=num;

            if(Yueyue>end){
                Yueyue=end-(Yueyue-end);
            }
            cnt=0;
            while(gap[Yueyue]!=-1){
                if(cnt>n){
                    flag=false;
                    break;
                }
                cnt++;
                Yueyue=gap[Yueyue];
            }
            if(!flag){
                printf("Impossible\n");
                break;
            }
            if(Yueyue==end){
                printf("Yueyue\n");
                break;
            }
            if(Lele==Yueyue)
                Lele=0;
            if(vis[Lele][Yueyue][num][1]){
                printf("Impossible\n");
                break;
            }
            vis[Lele][Yueyue][num][1]=1;
         //   printf("y:%d %d\n",Yueyue,num);
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值