嘘~ 正在从服务器偷取页面 . . .

UVA11214 Guarding the Chessboard 题解


UVA11214 Guarding the Chessboard 题解

题目链接:UVA11214 Guarding the Chessboard

题意

多组数据。输入一个 \(n×m\) 的棋盘( \(n,m<10\) ),某些格子有标记。

用最少的皇后守卫(即占据或者攻击)所有带标记的格子。

显然是搜索,这道题的特点在于搜索的深度可能及其大,所以我们需要用迭代加深搜索 (IDA star)。

所谓迭代加深搜索,就是限制一个搜索深度的上限,在本题中我们可以限制放的棋子数量。

因为 \(8\times 8\) 的棋盘都只需要 \(5\) 个皇后,所以实际运行的效率还是比较高的。

时间复杂度 \(\mathcal{O}(\text{ok})\)

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
void up(int &x,int y) { x < y ? x = y : 0; }
void down(int &x,int y) { x > y ? x = y : 0; }
#define N ((int)(15))

char s[N],g[N][N],vis[4][N * 2 + 15];
int n,m,cases,mxdep;
void init() { memset(vis, 0, sizeof(vis)); }
bool check()
{
    for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) {
        if(g[i][j]&&!vis[0][i]&&!vis[1][j]&&!vis[2][i+j]&&!vis[3][i-j+N])
            return false;
    }
    return true;
}
bool dfs(int x,int y,int dep)
{
    if(dep == mxdep) return check();
    for(int a,b,c,d; x <= n; ++x, y = 1) {
        for(; y <= m; y++)
        {
            a = vis[0][x], b = vis[1][y], c = vis[2][x + y], d = vis[3][x - y + N];
            vis[0][x] = vis[1][y] = vis[2][x + y] = vis[3][x - y + N] = 1;
            if(dfs(x, y+1, dep + 1)) return true;
            vis[0][x] = a, vis[1][y] = b, vis[2][x + y] = c, vis[3][x - y + N] = d;
        }
    }
    return false;
}
void solve()
{
    for(int i = 1; i <= n; i++)
    {
        cin >> (s + 1);
        for(int j = 1; j <= m; j++) g[i][j] = (s[j] == 'X');
    }
    for(mxdep = 0; ; ++mxdep) if(init(), dfs(1,1,0)) break;
    cout << "Case " << ++cases << ": " << mxdep << '\n';
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    // freopen("check.in","r",stdin);
    // freopen("check.out","w",stdout);
    while(cin >> n >> m, n) solve();
    return 0;
}

文章作者: q779
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 q779 !
评论
  目录