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;

}

/**/

你可能感兴趣的:(gnome)