#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define INPUT
using namespace std;
const int c0de4fun = 10;
int x[4] = {1,-1,0,0};
int y[4] = {0,0,1,-1};
int maze[c0de4fun][c0de4fun];
/**
Problem :HDOJ/HDU1072 - Nightmare
Begin Time:Unknown
End Time:Unknown
Test Data:
有一个146K的超级大测试文件,需要的可以PM我
Output:用本程序对拼即可
思路:
广度优先搜索+模拟,不用剪枝,不用记录已访问节点。记得把bombResetEquipment改成0或者改成1
教训:
WA了几次,教训主要有两点:
1,看题要仔细,本题中bombResetEquipment只能用一次就消失了,我以为能用很多次。
2,在搜索中,自带限制条件的,一般来说就不用mark已经访问过的节点了
所谓的限制条件,就是在一定步数之后可以让节点消失(不被重复访问)的条件
本题中我的重大!!!错误!!!就在于,当访问了bombResetEquipment之后就
mark掉这个点,然后把visited清空,并记录每个bombResetEquipment的位置,重新从这几个位置开始搜索。
但是这会导致一个问题,有些未扩展的状态就被清空了。在146K的测试数据中可以看到这点
这种情况可以是以下状况:
遇到了BRE,visited清空了,但是当前从BRE开始搜索,导致
从开始'3'点通往出口的某个点得状态变成了“已访问”,并且从BRE开始搜索不能达到出口
但是从开始点搜索是可以达到的,由于开始点通往出口的点被标注visited了,所以不能从这个点搜索了。
导致不出正确结果。
*/
struct node
{
int x;
int y;
int time;
int depth;
};
queue<node> nodes;
void Solve(int startx,int starty,int N,int M)
{
node tmp;
bool isExisted = false;
tmp.depth = 0;
tmp.time = 6;
tmp.x = startx;
tmp.y = starty;
nodes.push(tmp);
while( !nodes.empty() )
{
tmp = nodes.front();nodes.pop();
if( maze[tmp.x][tmp.y] == 4)
{
tmp.time = 6;
maze[tmp.x][tmp.y] = 0;
///这里还要mark一下
}
if( maze[tmp.x][tmp.y] == 3)
{
printf("%d\n",tmp.depth);isExisted = true;break;
}
for(int i = 0 ; i < 4; i++)
{
node tmp1 = tmp;
tmp1.x = tmp.x + x[i];
tmp1.y = tmp.y + y[i];
tmp1.depth = tmp.depth + 1;
tmp1.time = tmp.time - 1;
if( tmp1.x < 1 || tmp1.x > N || tmp1.y < 1 || tmp1.y > M)
continue; //数组越界
if( tmp1.time <= 0 )
continue;
if ( maze[tmp1.x][tmp1.y] == 0 )
continue;
nodes.push(tmp1);
}
}
if(!isExisted)
{
printf("-1\n");
}
while(!nodes.empty())
nodes.pop();
}
int main()
{
int T;
int N,M;
int startx,starty;
#ifdef INPUT
freopen("b:\\acm\\hdu1072\\input.txt","r",stdin);
//freopen("b:\\acm\\hdu1072\\output.txt","w",stdout);
#endif
scanf("%d",&T);
for(int t = 0 ; t < T; t++)
{
memset(maze,0,sizeof(int)*c0de4fun*c0de4fun);
scanf("%d%d",&N,&M);
for(int i = 1; i<=N; i++)
{
for(int j = 1; j<=M; j++)
{
scanf("%d",&maze[i][j]);
if(maze[i][j] == 2)
{
startx = i;
starty = j;
}
}
}
Solve(startx,starty,N,M);
}
#ifdef INPUT
fclose(stdin);
//fclose(stdout);
#endif
return 0;
}
【HDU1072】Nightmare,思路+解题报告+代码
最新推荐文章于 2019-09-15 22:42:49 发布