P1219 [USACO1.5]八皇后 Checker Challenge 深度搜索 标记 回溯

P1219 [USACO1.5]八皇后 Checker Challenge

好像是紫书上面的题目,没有想象的那么难.

标记的思想.

n最大才13,可以深搜,但是搜的过程中就得把不可能情况排除掉,不然搜一年(虚指).

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

int n, ct, s[20];
bool used[20];

void dfs(int pos)
{
    if (pos != n)
    {
        for (int i = 1; i <= n; i++)
            if (!used[i])
            {
                bool bad = false;
                for(int j = 0; j < pos; j++)
                    if(s[j] + j == pos + i || s[j] - j == i - pos)
                    {
                        bad = true;
                        break;
                    }
                if(bad)
                    continue;
                used[i] = true;
                s[pos] = i;
                dfs(pos + 1);
                used[i] = false;
            }
    }
    else
    {
        ct++;
        if (ct <= 3)
        {
            for (int i = 0; i < n; i++)
                printf("%d ", s[i]);
            putchar('\n');
        }
    }
}

int main()
{
    cin >> n;

    dfs(0);
    cout << ct << endl;

    return 0;
}

这样就过了,但是剪枝效率太低了,险些超时.

更好的策略是每放置一枚棋子,将该棋子所在的对角线的"特征值"s[pos] + pos标记为已用,检查下一颗棋子的时候就可以很快排除非法的位置了.

posted @ 2020-11-24 10:12  goverclock  阅读(115)  评论(0编辑  收藏  举报