HDU 1072 Nightmare
2015-07-26 19:23
337 查看
题目地址:点击打开链接
思路:
感觉还是挺难的,主要是走过的路还可以再走,刚开始直接DFS和猜的没错,死循环了,
没办法,总想验证一下想的对不?接着改,原来是要把每次走过的点记录下来,要是再次走过这个点时,距离爆炸的时间没有比原来的还短就不用走了,比原来爆炸的更快,没必要走,可以直接减枝,减了一下午没减出来,我也是服了,好那就BFS,超内存,就想走过的点没必要再走了吧,就把走过的点全标记为0,然后第三个测试数据就错了,用网上的代码把正确的路径打印出来,终于发现,走过的路有时候还是要必须走的,
如,第三个测试数据
5 8
1 2 1 1 1 1 1 4
1 0 0 0 1 0 0 1
1 4 1 0 1 1 0 1
1 0 0 0 0
3 0 1
1 1 4 1 1 1 1 1
看出来了吧,要是不走4过一会就爆了,根本走不到3,所以走到坐标(2,0)然后走到(2,1)接着返回坐标(2,0),所以会产生重复走的坐标,看了网上代码才想明白,其实有些地方我没减枝,所以会超内存,把加过时间的点标记为走过,以后的就不用再走了,这样就能省不少内存,因为下一次的点再次走到4的时候时间变成6,但是后来的点来到4的时候,前面已经用过的时间大于等于第一次来到4的时候所用的时间,而题目要求的是输出最短的时间,
虽然AC了,但是我想这么搞下去不会爆栈吗?又把走过的路径和步数打印出来,发现刚开始进栈的比较少,点到达对角线时进栈的最多,而后进栈的又会变小,所以保证在对角线
附近不会爆栈整个程序就不会爆栈,而题目给的矩形的面积最大是8乘以8的,肯定爆不了,数据再大一点非得爆栈不可
AC代码:
#include<stdio.h>
#include<queue>
using namespace std;
int m,n;
int cf[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
int a[9][9];
struct node
{
int x,y,step,time;
}p,q;
void bfs(int x,int y)
{
int i;
queue<node> que;
p.x = x;
p.y = y;
p.time = 6;
p.step = 0;
que.push(p);
a[x][y] = 0;
while(!que.empty())
{
p = que.front();
que.pop();
for(i=0; i<4; i++)
{
q = p;
q.x += cf[i][0];
q.y += cf[i][1];
if(q.x >= 0 && q.y >= 0 && q.x < n && q.y < m && a[q.x][q.y] !=0)//注意是大于等于零
{
if(a[q.x][q.y] == 1)
{
q.time--;
if(q.time > 0)
{
q.step++;
que.push(q);
}
}
else if(a[q.x][q.y] == 4)
{
q.time--;
if(q.time > 0)
{
q.step++;
q.time = 6;
que.push(q);
}
a[q.x][q.y] = 0;
}
else if(a[q.x][q.y] == 3)
{
q.time--;
if(q.time > 0)
{
q.step++;
printf("%d\n",q.step);
return;
}
}
}
}
}
printf("-1\n");
}
int main()
{
int t,i,j,starti,startj;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
scanf("%d",&a[i][j]);
if(a[i][j] == 2)
{
starti = i;
startj = j;
}
}
}
bfs(starti,startj);
}
return 0;
}
思路:
感觉还是挺难的,主要是走过的路还可以再走,刚开始直接DFS和猜的没错,死循环了,
没办法,总想验证一下想的对不?接着改,原来是要把每次走过的点记录下来,要是再次走过这个点时,距离爆炸的时间没有比原来的还短就不用走了,比原来爆炸的更快,没必要走,可以直接减枝,减了一下午没减出来,我也是服了,好那就BFS,超内存,就想走过的点没必要再走了吧,就把走过的点全标记为0,然后第三个测试数据就错了,用网上的代码把正确的路径打印出来,终于发现,走过的路有时候还是要必须走的,
如,第三个测试数据
5 8
1 2 1 1 1 1 1 4
1 0 0 0 1 0 0 1
1 4 1 0 1 1 0 1
1 0 0 0 0
3 0 1
1 1 4 1 1 1 1 1
看出来了吧,要是不走4过一会就爆了,根本走不到3,所以走到坐标(2,0)然后走到(2,1)接着返回坐标(2,0),所以会产生重复走的坐标,看了网上代码才想明白,其实有些地方我没减枝,所以会超内存,把加过时间的点标记为走过,以后的就不用再走了,这样就能省不少内存,因为下一次的点再次走到4的时候时间变成6,但是后来的点来到4的时候,前面已经用过的时间大于等于第一次来到4的时候所用的时间,而题目要求的是输出最短的时间,
虽然AC了,但是我想这么搞下去不会爆栈吗?又把走过的路径和步数打印出来,发现刚开始进栈的比较少,点到达对角线时进栈的最多,而后进栈的又会变小,所以保证在对角线
附近不会爆栈整个程序就不会爆栈,而题目给的矩形的面积最大是8乘以8的,肯定爆不了,数据再大一点非得爆栈不可
AC代码:
#include<stdio.h>
#include<queue>
using namespace std;
int m,n;
int cf[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
int a[9][9];
struct node
{
int x,y,step,time;
}p,q;
void bfs(int x,int y)
{
int i;
queue<node> que;
p.x = x;
p.y = y;
p.time = 6;
p.step = 0;
que.push(p);
a[x][y] = 0;
while(!que.empty())
{
p = que.front();
que.pop();
for(i=0; i<4; i++)
{
q = p;
q.x += cf[i][0];
q.y += cf[i][1];
if(q.x >= 0 && q.y >= 0 && q.x < n && q.y < m && a[q.x][q.y] !=0)//注意是大于等于零
{
if(a[q.x][q.y] == 1)
{
q.time--;
if(q.time > 0)
{
q.step++;
que.push(q);
}
}
else if(a[q.x][q.y] == 4)
{
q.time--;
if(q.time > 0)
{
q.step++;
q.time = 6;
que.push(q);
}
a[q.x][q.y] = 0;
}
else if(a[q.x][q.y] == 3)
{
q.time--;
if(q.time > 0)
{
q.step++;
printf("%d\n",q.step);
return;
}
}
}
}
}
printf("-1\n");
}
int main()
{
int t,i,j,starti,startj;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
scanf("%d",&a[i][j]);
if(a[i][j] == 2)
{
starti = i;
startj = j;
}
}
}
bfs(starti,startj);
}
return 0;
}
相关文章推荐
- ORA-12528: TNS:listener: all appropriate instances are blocking new connections
- PAT (Advanced Level) 1049. Counting Ones (30) 1到N中1出现的次数
- iOS 中KVC、KVO、NSNotification、delegate 总结及区别
- Android 开发--CSDN博客大神汇总
- hdu3308LCIS 线段树
- equals与==之间的区别
- 二分图的最大匹配 (匈牙利算法)再续
- 【染色】 HDU 5313 Bipartite Graph
- 根据输入的内容打印出菱形
- 关于bitmap的回收问题
- HDU1005(周期问题)
- 源码分析之一:abator工程架构
- vc 编译器的一些精典报错
- B+树在数据库中的应用
- VNC配置
- 机房收费—组合查询
- win8下向qt5.4.1安装 qwt-6.1.2
- POJ1700(过河问题)
- DDN - Digital Data Network
- Java map的匿名类的初始化