ZOJ 1008 Gnome Tetravex

DFS 题目,剪枝比较重要,这里使用的是把重复的方块只记录一次,用 num[] 保存它的数目。

# include <cstdio>
# include <cstring>

# define N 25 + 2

bool finished;
int n, m, t[N][4], num[N], ans[N];

void dfs(int cnt)
{
    if (cnt == n*n) {finished = true; return ;}
    int x = cnt/n + 1, y = cnt%n + 1;
    int left = cnt, top = cnt+1-n;
    for (int i = 0; i < m; ++i) if (num[i])
    {
        bool ok = true;
        if (x!=1 && t[i][0] != t[ans[top]][2]) ok = false;
        if(ok && y!=1 && t[i][3] != t[ans[left]][1]) ok = false;
        if (ok)
        {
            --num[i];
            ans[cnt+1] = i;
            dfs(cnt+1);
            if(finished) return ;
            ++num[i];
        }
    }
}

void init(void)
{
    bool rpt;
    int top, rig, bot, lef;

    m = 0;
    memset(num, 0, sizeof(num));
    for (int i = 0; i < n*n; ++i)
    {
        rpt = false;
        scanf("%d%d%d%d", &top, &rig, &bot, &lef);
        for (int j = 0; j < m; ++j)
        {
            if (t[j][0] == top && t[j][1] == rig &&
                t[j][2] == bot && t[j][3] == lef)
                {
                    rpt = true;
                    ++num[j];
                    break;
                }
        }
        if (rpt) continue;
        t[m][0] = top, t[m][1] = rig, t[m][2] = bot, t[m][3] = lef;
        ++num[m];
        ++m;
    }
}

void solve(void)
{
    finished = false;
    dfs(0);
    if (finished) puts("Possible");
    else puts("Impossible");
}

int main()
{
    int i = 0;

    while (~scanf("%d", &n))
    {
        if (!n) break;
        init();
        if(i != 0) putchar('\n');
        printf("Game %d: ", ++i);
        solve();
    }

    return 0;
}

/**/

原文地址:https://www.cnblogs.com/JMDWQ/p/2597737.html