ZOJ 1008 Gnome Tetravex

12 篇文章 0 订阅

题意:给你若干的正方形,将每个正方形分成四个三角形,判断是否存在每个正方形中的三角形与相邻正方形中的相邻的三角形中的数字相同。

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=8

思路:DFS+回溯搜索所有可能,简单题。

注意点:剪枝:对相同图形进行压缩,同一个位置中相同的正方形只判断一次。(第一次没有想到这个剪枝,TLE了一次)


以下为AC代码:

Run IDSubmit TimeJudge StatusProblem IDLanguageRun Time(ms)Run Memory(KB)User Name
37788062014-09-23 08:14:40Accepted 1008C++0x1560276luminus
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

struct node
{
    int up;
    int right;
    int down;
    int left;
};
struct node map[100];
int vis[100];
int t;
bool flag;
int dir[4][2] = { 1, 0, -1, 0, 0, 1, 0, -1 };
struct node zero = { 0, 0, 0, 0 };
struct node path[10][10];
int cnt = 0;

void init ()
{
    memset ( path, 0, sizeof ( path ) );
    memset ( vis, false, sizeof ( vis ) );
    memset ( map, 0, sizeof ( map ) );
}

void input( int k )
{
    int up;
    int right;
    int down;
    int left;
    int i;
    scanf ( "%d%d%d%d", &up, &right, &down, &left );
    for ( i = 0; i < cnt; i ++ )
    {
        if ( map[i].up == up && map[i].right == right && map[i].down == down && map[i].left == left )
        {
            break;
        }
    }
    if ( i == cnt )
    {
        //cout << i << endl;
        map[i].up = up;
        map[i].right = right;
        map[i].down = down;
        map[i].left = left;
        cnt ++;
        vis[i] = 1;
    }
    else
    {
        vis[i] ++;
    }

}

void dfs ( int num )
{
    int x = num / t;
    int y = num % t;
    //cout << num << endl;//test output
    if ( num == t * t )
    {
        flag = 1;
        return;
    }
    for ( int i = 0; i < cnt; i ++ )
    {
        //cout << "Begin vis[" << i << "] = " << vis[i] << endl;
        if ( vis[i] == 0 )
        {
            continue;
        }
        //bool si = true;
        vis[i] -= 1;
        if ( x - 1 >= 0 )
        {
            //printf ( "map[%d].up = %d, path[%d][%d].down = %d\n", i, map[i].up, x - 1, y, path[x -1][y].down );
            if ( map[i].up != path[x - 1][y].down )
            {
                vis[i] += 1;
                continue;
                //si = false;
            }
        }
        if ( y - 1 >= 0 )
        {
            //printf ( "map[%d].left = %d, path[%d][%d].right = %d\n", i, map[i].left, x, y - 1, path[x][y - 1].right );
            if ( map[i].left != path[x][y - 1].right )
            {
                vis[i] += 1;
                continue;
                //si = false;
            }
        }
        path[x][y] = map[i];
        //cout << cnt << endl;
        dfs ( num + 1 );
        if ( flag )
        {
            return;
        }
        vis[i] += 1;
        //cout << "vis[" << i << "]= " << vis[i] << endl;
        //cout << i << ' ' << cnt << endl;
    }
}

int main()
{
    int n = 1;
    while ( cin >> t && t )
    {
        flag = 0;
        cnt = 0;
        init ();
        if ( n != 1 )
        {
            cout << endl;
        }
        for ( int i = 0; i < t * t; i ++ )
        {
            input ( i );
        }

       /* for ( int i = 0; i < cnt; i ++ )//test output
        {
            cout << map[i].up << ' ' << map[i].right << ' '
                 << map[i].down << ' ' << map[i].left << endl;
            cout << "vis = " << vis[i] << endl;
        }*/

        dfs( 0 );
        if ( flag )
        {
            printf (  "Game %d: Possible\n", n ++ );
        }
        else
        {
            printf ( "Game %d: Impossible\n", n ++ );
        }
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值