习题7-10:守卫棋盘(dfs迭代加深)

来源:互联网 发布:java volatile atomic 编辑:程序博客网 时间:2024/06/12 01:32

习题7-10:守卫棋盘
给出m*n棋盘上的目标点,求最少用几个皇后可以守卫所有目标点。
类似八皇后做法,2维数组标记行、列、主对角线、副对角线。
有个加速的技巧,测试之后发现10*10的棋盘全部守卫至少需要5个,所以上限就是5,当maxd等于5时直接输出,不进行搜索。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<string>#include<cmath>#include<set>#include<queue>#include<map>#include<stack>#include<vector>#include<list>#include<deque>using namespace std;typedef long long ll;const int maxn = 1e6 + 10;const double eps = 1e-6;const int INF = 1 << 30;const int dir[4][2] = {1,0,0,1,0,-1,-1,0};int n, m, maxd;bool Map[12][12], vis[4][50];bool input(){    cin >> n;    if(!n)return false;    cin >> m;    char x;    memset(Map, 0, sizeof(Map));    for(int i = 0; i < n; i++)    {        for(int j = 0; j < m; j++)        {            cin >> x;            if(x == 'X')Map[i][j] = 1;        }    }    return true;}bool judge(){    for(int i = 0; i < n; i++)    {        for(int j = 0; j < m; j++)        {            if(Map[i][j] && !vis[0][i] && !vis[1][j] && !vis[2][i + j] && !vis[3][i - j + 11])return false;        }    }    return true;}bool dfs(int d, int i, int j){    if(d == maxd)    {        if(judge())return true;        return false;    }    for(; i < n; i++)    {        for(; j < m; j++)        {            bool tmp1 = vis[0][i], tmp2 = vis[1][j], tmp3 = vis[2][i + j], tmp4 = vis[3][i - j + 11];            vis[0][i] = vis[1][j] = vis[2][i + j] = vis[3][i - j + 11] = 1;            if(dfs(d + 1, i, j + 1))return true;            vis[0][i] = tmp1;            vis[1][j] = tmp2;            vis[2][i + j] = tmp3;            vis[3][i - j + 11] = tmp4;        }        j = 0;    }    return false;}int main(){    int cases = 0;    while(input())    {        for(maxd = 0; maxd < 5; maxd++)        {            memset(vis, 0, sizeof(vis));            if(dfs(0, 0, 0))break;        }        printf("Case %d: %d\n", ++cases, maxd);    }    return 0;}
原创粉丝点击