http://acm.hdu.edu.cn/showproblem.php?pid=1728

这两道题花了一下午的时候调试,因为以前做过类似的题,但是判断方向的方法是错的,一直没发现啊,真无语。

每个状态除了坐标外还需要记录步数,和方向。还要注意输入格式。

并且每一个点并不是走过了就不能在走,只要到达这个点的时候转向次数少的就可以更新这个点,可以等于。千万注意这个坑。

 #include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
int n,m,k;
int dir[][]={{,},{,},{,-},{-,}};
char mp[][];
int used[][];
struct point
{
int x,y,d,time;
bool operator < (const point a) const
{
return time>a.time;
}
};
void bfs(int x1,int y1,int x2,int y2)
{
//printf("%d %d %d %d\n",x1,y1,x2,y2);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++) used[i][j]=<<;
priority_queue<point>que;
point s;
s.x=x1,s.y=y1,s.d=-,s.time=;
que.push(s);
used[s.x][s.y]=;
while(!que.empty())
{
point e=que.top(); que.pop();
printf("%d %d %d\n",e.x,e.y,e.time);
if(e.time>k) continue;
if(e.x==x2&&e.y==y2) {printf("yes\n");return;}
for(int i=;i<;i++)
{
s.x=e.x+dir[i][];
s.y=e.y+dir[i][];
if(s.x<||s.x>=n||s.y<||s.y>=m||mp[s.x][s.y]=='*') continue;
s.d=i;
if(s.d!=e.d&&e.d!=-) //转向次数加1 并且保证不会往回走构成死循环
{
s.time=e.time+;
}
else s.time=e.time;
if(s.time<=used[s.x][s.y]&&s.time<=k) //注意
{
used[s.x][s.y]=s.time;
que.push(s);
}
}
}
printf("no\n");
} int main()
{
freopen("a.txt","r",stdin);
int t,x1,y1,x2,y2;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
getchar();
for(int i=;i<n;i++)
scanf("%s",&mp[i]);
scanf("%d",&k);
scanf("%d%d%d%d",&y1,&x1,&y2,&x2);
//printf("%d %d %d %d\n",x1-1,y1-1,x2-1,y2-1);
bfs(x1-,y1-,x2-,y2-);
}
return ;
}

知道写bfs了 换成dfs还是挺容易的。

并且bfs是1400ms,dfs只有31ms。

#include <cstdio>
#include <cstring>
char mp[][];
int n,m,k;
int dir[][]={{-,},{,},{,},{,-}};
int x2,y2;
bool flag;
int vis[][]; void dfs(int x,int y,int d,int step)
{
//printf("%d %d %d %d\n",x,y,d,step);
if(flag) return;
if(x==x2&&y==y2&&step<=k)
{
flag=;
printf("yes\n");
return;
}
for(int i=;i<;i++)
{
int xx=x+dir[i][];
int yy=y+dir[i][];
int dd=i;
if(xx>=&&xx<n&&yy>=&&yy<m&&mp[xx][yy]!='*')
{
int s=step;
if(d!=dd&&d!=-) s++;
if(s<=vis[xx][yy]&&s<=k) //强力的剪枝
{
vis[xx][yy]=s;
dfs(xx,yy,dd,s);
}
}
}
}
int main()
{
// freopen("a.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++) scanf("%s",mp[i]);
int x1,y1;
scanf("%d%d%d%d%d",&k,&y1,&x1,&y2,&x2);
flag=;
for(int i=;i<=n;i++)
for(int j=;j<m;j++) vis[i][j]=<<;
x1--,y1--;
x2--,y2--;
vis[x1][y1]=;
dfs(x1,y1,-,);
if(!flag) printf("no\n");
}
return ;
}

http://acm.hdu.edu.cn/showproblem.php?pid=1175

这个题的坑点在于只能两个端点是非0数,不能经过其他的数字。

思路是一样的。

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
int n,m;
int dir[][]={{,},{,},{,-},{-,}};
int mp[][];
int used[][];
struct point
{
int x,y,d,time;
bool operator < (const point a) const
{
return time>a.time;
}
};
point t;
bool bfs(point s)
{
for(int i=;i<=n;i++)
for(int j=;j<=m;j++) used[i][j]=<<;
priority_queue<point>que;
que.push(s);
used[s.x][s.y]=;
while(!que.empty())
{
point e=que.top(); que.pop(); if(e.x==t.x&&e.y==t.y) return true;
for(int i=;i<;i++)
{
s.x=e.x+dir[i][];
s.y=e.y+dir[i][];
s.d=i; if(s.x<||s.x>n||s.y<||s.y>m) continue;
if(mp[s.x][s.y]!=&&(s.x!=t.x||s.y!=t.y)) continue; //注意别逻辑别写错了
//printf("%d %d %d\n",s.x,s.y,s.time);
if(s.d!=e.d&&e.d!=-) s.time=e.time+;
else s.time=e.time;
if(s.time<=used[s.x][s.y]&&s.time<=)
{
used[s.x][s.y]=s.time;
que.push(s);
}
}
}
return false;
} int main()
{
//freopen("a.txt","r",stdin);
int q,x1,y1,x2,y2;
while(~scanf("%d%d",&n,&m))
{
if(n==&&m==) break;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++) scanf("%d",&mp[i][j]);
scanf("%d",&q);
while(q--)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(!mp[x1][y1]||mp[x1][y1]!=mp[x2][y2]) printf("NO\n");
else
{
point s;
s.x=x1,s.y=y1,s.d=-,s.time=;
t.x=x2,t.y=y2;
if(bfs(s)) printf("YES\n");
else printf("NO\n");
}
}
}
return ;
}

hdu - 1728逃离迷宫 && hdu - 1175 连连看 (普通bfs)的更多相关文章

  1. hdu 1728 逃离迷宫 bfs记转向

    题链:http://acm.hdu.edu.cn/showproblem.php?pid=1728 逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Mem ...

  2. hdu 1728 逃离迷宫 bfs记步数

    题链:http://acm.hdu.edu.cn/showproblem.php?pid=1728 逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Mem ...

  3. HDU 1728 逃离迷宫(DFS)

    题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1728 题目: 逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)  ...

  4. HDU 1728 逃离迷宫(DFS经典题,比赛手残写废题)

    逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  5. HDU 1728 逃离迷宫

    [题目描述 - Problem Description] 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,glo ...

  6. HDU 1728 逃离迷宫(DFS||BFS)

    逃离迷宫 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可 ...

  7. hdu 1728 逃离迷宫 [ dfs ]

    传送门 逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  8. hdu 1728:逃离迷宫(DFS,剪枝)

    逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  9. hdu 1728 逃离迷宫 (BFS)

    逃离迷宫 Time Limit : 1000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Total Submissi ...

随机推荐

  1. 【BZOJ】【3442】学习小组

    网络流/费用流 orz zyf 裸的费用流,根据题目描述即可建出如下的图: S->i 费用表示每有一个加入第 i 个小组的学生,需要花的钱,由于是跟流量(人数)的二次方相关,所以要拆边……然后每 ...

  2. File not found images\Thumbs.db.

    启动eclipse正常,部署项目的时候发生这个错误. 解决办法: 1. 从tomcat中删除这个项目,并清空work目录下的缓存 2. 在eclipse中执行project>Clean>C ...

  3. 系统使用 aspose.cell , 使得ashx第一次访问会变很慢

      网站放在IIS后, 在网站第一次访问后.  回收应用程序池 第一次访问aspx页面还是比较快.   但第一次访问ashx会很慢.   后发现原因: aspose.cell的5.3...版本. 的原 ...

  4. Javascript 性能优化的一点技巧

    把优秀的编程方式当成一种习惯,融入到日常的编程当中.下图是今天想到的一点Javascript 性能优化的技巧,分享一下,抛砖引玉.

  5. IOS Crash捕获

    IOS Crash ,就两种情况:一种是异常,另一种是中断[信号量]. #include <libkern/OSAtomic.h> #include <execinfo.h> ...

  6. Tech Stuff - Mobile Browser ID (User-Agent) Strings

    Tech Stuff - Mobile Browser ID (User-Agent) Strings The non-mobile stuff is here (hint: you get jerk ...

  7. Java 并发同步器之CountDownLatch、CyclicBarrier

    一.简介 1.CountDownLatch是一个同步计数器,构造时传入int参数,该参数就是计数器的初始值,每调用一次countDown()方法,计数器减1,计数器大于0 时,await()方法会阻塞 ...

  8. HDU Destroy Transportation system(有上下界的可行流)

    前几天正看着网络流,也正研究着一个有上下界的网络流的问题,查看了很多博客,觉得下面这篇概括的还是相当精确的: http://blog.csdn.net/leolin_/article/details/ ...

  9. 在linux服务器上装svn版本管理,自动部署代码到项目

    在linux服务器上装svn版本管理,自动部署代码到项目 http://bbs.aliyun.com/read/9715.html?spm=5176.7114037.1996646101.1.W3zw ...

  10. 《Thinking in C++》学习笔记(二)【第三章】

    第三章 C++中的C 3.4.4 指针简介 ‘&’运算符:只要在标识符前加上‘&’,就会得出标识符的地址. C和C++有一个专门存放地址的变量类型.这个变量类型叫做指针(pointer ...