uva 11818 Mouse & a Cheese

来源:互联网 发布:java class 编辑:程序博客网 时间:2024/06/06 05:15


Game – Mouse and Cheese 
Input: Standard Input

Output: Standard Output


SOHA and TARA have recently invented a new game called “Mouse and Cheese”. As the name suggests, this game involves a mouse searching for a piece of cheese. The game is played on a 3x3 board as shown in the diagram below. Each cell is uniquely numbered with an integer between 1 and 9. The board contains 12 sticks (the blue lines in the diagram).

 

 

 

 

 

 

 

 

 

 

Initially a mouse and a piece of cheese are placed on two different cells. In the example to the right, the mouse is placed on ‘cell 8’ and the cheese is placed on ‘cell 3’.

The rule of the game goes like this: It’s a two-player game where the players make moves alternately. SOHA, being player 1, goes first. In each move, the player selects a stick and throws it away. After each move, if the mouse can reach the cell containing the cheese without touching any of the remaining sticks, then that player is declared as the winner? If both play perfectly, who wins?

 

Before the game starts, some of the sticks are removed. You will be given the coordinates of these sticks and the cell numbers of the mouse and cheese. A stick is represented using the coordinates of its end points. The lower left of the grid is the origin (0, 0). The two sticks surrounding the cheese, in the example above, has coordinates “2 0 2 1” and “2 1 3 1”.  Note that the end-points of a stick can be given in any order. That is “2 0 2 1” could be given as “2 1 2 0”.

 

Input

The first line of input is an integer T(T<1000) that determines the number of test cases. Each case starts with 3 integers S, C and R. S and Cdenotes the location of the mouse and cheese respectively. Each of the next R lines contains 4 space-separated integers that give the coordinates of the sticks removed from the board before the start of the game.

Notes and Constraints
1 <= S,C <= 9
S != C
0 <= R <= 12

For each case, all the removed sticks will be distinct.

 

Output

For each case, output the case number first, starting with 1, followed by the name of the player who wins. If the mouse can already reach the cheese before the game starts, output “No Cheese!” instead. Look at the samples for exact format.

 

Sample Input

Output for Sample Input

3

1 2 1

1 1 1 0

1 4 0

7 2 2

1 2 1 3

2 2 2 3

Case 1: No Cheese!

Case 2: SOHA

Case 3: TARA

 


Problemsetter: Sohel Hafiz

Special Thanks: Arifuzzaman Arif

  

题目大意:

一个老鼠想吃蛋糕,但是老鼠四周都被东西挡住了,两个人玩游戏,轮流拿掉一根火柴,问你谁能赢。


解题思路:

记忆优化DP,DP(当前的火柴的情况2^12,当前谁开始拿,老鼠的位置,蛋糕的位置)

转移也就是,当前这个人取他的最优解。暴力模拟了位运算,所以效率低了很多。


#include <iostream>#include <vector>#include <cstdio>#include <queue>using namespace std;const int maxn=(1<<12)+10;vector < vector<int> > v;int from,to;int a[5][5][5][5],dp[maxn][2][10][10],exist[15];void ini(){    for(int k=0;k<maxn;k++){        for(int i=0;i<10;i++){            for(int j=0;j<10;j++){                dp[k][0][i][j]=-1;                dp[k][1][i][j]=-1;            }        }    }    v.resize(10);    v[1].push_back(1);v[1].push_back(3);    v[2].push_back(1);v[2].push_back(2);v[2].push_back(4);    v[3].push_back(2);v[3].push_back(5);    v[4].push_back(3);v[4].push_back(6);v[4].push_back(8);    v[5].push_back(4);v[5].push_back(6);v[5].push_back(7);v[5].push_back(9);    v[6].push_back(5);v[6].push_back(7);v[6].push_back(10);    v[7].push_back(8);v[7].push_back(11);    v[8].push_back(9);v[8].push_back(11);v[8].push_back(12);    v[9].push_back(10);v[9].push_back(12);    a[1][0][1][1]=1;a[1][1][1][0]=1;    a[2][0][2][1]=2;a[2][1][2][0]=2;    a[0][1][1][1]=3;a[1][1][0][1]=3;    a[1][1][2][1]=4;a[2][1][1][1]=4;    a[2][1][3][1]=5;a[3][1][2][1]=5;    a[1][1][1][2]=6;a[1][2][1][1]=6;    a[2][1][2][2]=7;a[2][2][2][1]=7;    a[0][2][1][2]=8;a[1][2][0][2]=8;    a[1][2][2][2]=9;a[2][2][1][2]=9;    a[2][2][3][2]=10;a[3][2][2][2]=10;    a[1][2][1][3]=11;a[1][3][1][2]=11;    a[2][2][2][3]=12;a[2][3][2][2]=12;}bool can(){    int s=from;    queue <int> q;    bool visited[15];    for(int i=0;i<15;i++) visited[i]=false;    visited[s]=true;    q.push(s);    while(!q.empty()){        s=q.front();        q.pop();        for(int i=1;i<=9;i++){            if(visited[i]) continue;            for(int k=0;k<v[i].size();k++){                for(int t=0;t<v[s].size();t++){                    if(v[i][k]==v[s][t] && exist[v[i][k]]==false){                        visited[i]=true;                        if(i==to) return true;                        q.push(i);                    }                }            }        }    }    return visited[to];}void input(){    int n;    scanf("%d%d%d",&from,&to,&n);    while(n-- >0){        int t1,t2,t3,t4;        scanf("%d%d%d%d",&t1,&t2,&t3,&t4);        exist[a[t1][t2][t3][t4]]=false;    }}int DP(int now){    int sum=0;    for(int i=1;i<=12;i++){        if(exist[i]) sum+=(1<<(i-1));    }    if(dp[sum][now][from][to]!=-1) return dp[sum][now][from][to];    int ans;    if(now==0){        ans=1000;        for(int i=1;i<=12;i++){            if(exist[i]){                exist[i]=false;                if(can()) ans=now;                else{                    if(DP(1-now)<ans) ans=DP(1-now);                }                exist[i]=true;            }        }    }else{        ans=-1;        for(int i=1;i<=12;i++){            if(exist[i]){                exist[i]=false;                if(can()) ans=now;                else{                    if(DP(1-now)>ans) ans=DP(1-now);                }                exist[i]=true;            }        }    }    return dp[sum][now][from][to]=ans;}void computing(int casen){    if(can()) printf("Case %d: No Cheese!\n",casen);    else if(DP(0)==0) printf("Case %d: SOHA\n",casen);    else printf("Case %d: TARA\n",casen);}int main(){    int t;    ini();    scanf("%d",&t);    for(int i=0;i<t;i++){        for(int i=0;i<15;i++) exist[i]=true;        input();        computing(i+1);    }    return 0;}



2 0
原创粉丝点击