hdu 1045 || zoj 1002 Fire Net(搜索:DFS+水题)

来源:互联网 发布:安卓优化神器 编辑:程序博客网 时间:2024/05/21 12:40

很水的一道题,直接DFS即可

我的思路是假设当前位置可以放子弹

不放子弹搜一遍,放上子弹搜一遍并更新行列状态

但是有一个问题就是在当前位置放置子弹后,如何在深搜的过程中还原为不放子弹的状态

我开始的想法是用一个bool vis[]来表示当前位置是否可以放子弹

但这样是不行的,因为在搜索的过程中这个数组被多次赋值了,不可能再回到原来的状态了

之后我的想法是用一个三维数组cur[pos][x][y]来保存遍历到pos这个位置时图的状态

这样就很好做了,搜完放子弹状态后在把cur数组赋值给原来的数组,回到原来状态即可

代码如下:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAXN 5using namespace std;int n, ans = -1;int g[MAXN][MAXN], cur[17][MAXN][MAXN];void change(int pos) {    int x = pos/n;    int y = pos%n;    g[x][y] = -1;    int tmp = x;    while(tmp>=1 && g[--tmp][y]==0) {        g[tmp][y] = -1;    }    tmp = x;    while(tmp<n-1 && g[++tmp][y]==0) {        g[tmp][y] = -1;    }    tmp = y;    while(tmp>=1 && g[x][--tmp]==0) {        g[x][tmp] = -1;    }    tmp = y;    while(tmp<n-1 && g[x][++tmp]==0) {        g[x][tmp] = -1;    }}void unchange(int pos) {    for(int i=0; i<n; ++i)        for(int j=0; j<n; ++j)            g[i][j] = cur[pos][i][j];}void dfs(int pos, int times) {    if(pos == n*n) {        ans = max(ans, times);        return ;    }        for(int i=0; i<n; ++i)        for(int j=0; j<n; ++j)            cur[pos][i][j] = g[i][j];    dfs(pos+1, times);    if(g[pos/n][pos%n] == 0) {        change(pos);        dfs(pos+1, times+1);        unchange(pos);    }    return ;}int main(void) {    char ch;    while(scanf("%d", &n) && n) {        ans = -1;        memset(g, 0, sizeof(g));        memset(cur, 0, sizeof(cur));        for(int i=0; i<n; ++i) {            getchar();            for(int j=0; j<n; ++j) {                ch = getchar();                if(ch == 'X')                    g[i][j] = -1;            }        }        dfs(0, 0);        cout << ans << endl;    }    return 0;}


0 0
原创粉丝点击