ZOJ1008

Gnome Tetravex


Time Limit: 10 Seconds      Memory Limit: 32768 KB


Hart is engaged in playing an interesting game, Gnome Tetravex, these days. In the game, at the beginning, the player is given n*n squares. Each square is divided into four triangles marked four numbers (range from 0 to 9). In a square, the triangles are the left triangle, the top triangle, the right triangle and the bottom triangle. For example, Fig. 1 shows the initial state of 2*2 squares.


Fig. 1 The initial state with 2*2 squares

The player is required to move the squares to the termination state. In the termination state, any two adjoining squares should make the adjacent triangle marked with the same number. Fig. 2 shows one of the termination states of the above example.


Fig. 2 One termination state of the above example

It seems the game is not so hard. But indeed, Hart is not accomplished in the game. He can finish the easiest game successfully. When facing with a more complex game, he can find no way out.

One day, when Hart was playing a very complex game, he cried out, "The computer is making a goose of me. It‘s impossible to solve it." To such a poor player, the best way to help him is to tell him whether the game could be solved. If he is told the game is unsolvable, he needn‘t waste so much time on it.

Input

The input file consists of several game cases. The first line of each game case contains one integer n, 0 <= n <= 5, indicating the size of the game.

The following n*n lines describe the marking number of these triangles. Each line consists of four integers, which in order represent the top triangle, the right triangle, the bottom triangle and the left triangle of one square.

After the last game case, the integer 0 indicates the termination of the input data set.

Output

You should make the decision whether the game case could be solved. For each game case, print the game number, a colon, and a white space, then display your judgment. If the game is solvable, print the string "Possible". Otherwise, please print "Impossible" to indicate that there‘s no way to solve the problem.

Print a blank line between each game case.

Note: Any unwanted blank lines or white spaces are unacceptable.

Sample Input

2
5 9 1 4
4 4 5 6
6 8 5 4
0 4 4 3
2
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
0

Output for the Sample Input

Game 1: Possible

Game 2: Impossible

思路分析:

本题是我第一次做,代码也是自己模仿出来的。本体可以考虑如下填充方式:

我们可以按照箭头所指的方向填满整个框。

下面我们设计我们的dfs函数:

 1 bool solve(int locate){  //找出第locate位置应该放那种类型的方块,和深搜差不多
 2
 3     if(locate==line*line)
 4         return true;
 5
 6     int x=locate/line,y=locate%line,i;//求出locate在棋盘中的相对位置,以便于剪枝
 7
 8     for(i=0;i<all;i++)
 9     {
10
11         if(squaresnum[i]==0)
12             continue;
13         if(x>0 && squares[fillsquares[locate-line]].d!=squares[i].u )
14             //它不是第一行并且上一个方块的下面与它的上面不相等
15             continue; //继续下一次判断
16         if(y>0 && squares[fillsquares[locate-1]].r!=squares[i].l)
17             //它不是第一列并且左边的方块的右边与它的左面不相等
18             continue;
19         fillsquares[locate]=i; // locate位置可以放第i种方块
20         squaresnum[i]--; //第i种方块减少一个
21         if(solve(locate+1)) return true;//这个return true还是很重要的 ,判断如果能走完所有路径,则返回true
22         squaresnum[i]++;//如果下一个不合适了,得回溯一个方块
23     }
24     return false;
25 }

下面交ac代码:

#include <iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define maxnum 26
typedef struct{
    int l,r,u,d;
}data;
data squares[maxnum];//squares是输入的各种方块的类型数组,最多有25种类型
int squaresnum[maxnum],fillsquares[maxnum],testnum=0,line,all;//squaresnum是对应每一种类型方块的数量
//fillsquares是每一个位置的数组,指明应该放哪一种类型的方块
//line是几行几列,all是总共有的方块类型的数目
bool Judge(data Temp,data Compare){
    if(Temp.d==Compare.d && Temp.l==Compare.l
        && Temp.r==Compare.r && Temp.u==Compare.u)
        return true;
    return false;
}
void Input(){

    all=0;
    memset(squaresnum,maxnum,0);
    for(int i=0,j ;i<line*line;i++){
       data Temp;
       cin>>Temp.u>>Temp.r>>Temp.d>>Temp.l;
       for(j=0;j<all;j++){  //判断方块类型是否已经存在,存在可不添加,数量加1
            if( Judge(Temp,squares[j]) ){
               squaresnum[j]++;
               break;  //跳出循环
            }
        }
        if(j==all) //如果不存在,则添加
            squares[all]=Temp,squaresnum[all++]=1;
    }
}
bool solve(int locate){  //找出第locate位置应该放那种类型的方块,和深搜差不多

    if(locate==line*line)
        return true;

    int x=locate/line,y=locate%line,i;//求出locate在棋盘中的相对位置,以便于剪枝

    for(i=0;i<all;i++)
    {

        if(squaresnum[i]==0)
            continue;
        if(x>0 && squares[fillsquares[locate-line]].d!=squares[i].u )
            //它不是第一行并且上一个方块的下面与它的上面不相等
            continue; //继续下一次判断
        if(y>0 && squares[fillsquares[locate-1]].r!=squares[i].l)
            //它不是第一列并且左边的方块的右边与它的左面不相等
            continue;
        fillsquares[locate]=i; // locate位置可以放第i种方块
        squaresnum[i]--; //第i种方块减少一个
        if(solve(locate+1)) return true;//这个return true还是很重要的
        squaresnum[i]++;//如果下一个不合适了,得回溯一个方块
    }
    return false;
}
int main(){

    while(cin>>line && line )
    {

        if(testnum)
            cout<<endl;
        Input();
        cout<<"Game "<<++testnum<<": ";
        puts(solve(0)?"Possible":"Impossible");
    }
    return 0;
}

ZOJ1008

时间: 2024-08-07 00:46:51

ZOJ1008的相关文章

ZOJ1008 Gnome Tetravex(DFS)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1008 题意: 哈特近来一直在玩有趣的 Gnome Tetravex 游戏.在游戏开始时,玩家会得到 n×n(n≤5) 个正方形.每个正方形都被分成 4个标有数字的三角形(数字的范围是 0到9).这四个三角形分 别被称为"左三角形"."右三角形"."上三角形"和"下三角形".例如,图 2.12(

ZOJ1008 Gnome Tetravex

DFS+剪枝~ #include<bits/stdc++.h> using namespace std; int a[30][4]; int N; int cnt; int c[30]; int p[30]; unordered_map<long long,int> pos; bool dfs (int v) { if (v==N*N) return true; for (int i=0;i<cnt;i++) { if (c[i]==0) continue; if (v%N!