nyoj82迷宫寻宝(一)(关键是对于门的处理)

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=82 

题目解析:本题主要注意对门的处理,如果当前门的所有钥匙都找到了,那么这个门就可以当做点,否则的话,加入队列,但不进行标记,意思就是说可以多次访问,直到无路可走,或者找到目标,或者找到所有的钥匙。

代码如下:

01. #include<cstdio>
02. #include<cstring>
03. #include<algorithm>
04. #include<queue>
05. using namespace std;
06. struct node
07. {
08. int x;
09. int y;
10. }n1,n2;
11. int dx[4]={0,0,1,-1};
12. int dy[4]={1,-1,0,0};
13. int k[6];
14. int m,n;
15. int begin_x,begin_y;
16. char map[25][25];
17. bool vis[25][25];
18. bool judge(int x,int y)
19. {
20. if(x<0||x>=m||y<0||y>=n||vis[x][y])  return false;
21. if(map[x][y]=='X')  return false;
22. if(map[x][y]>='a'&&map[x][y]<='e')   k[map[x][y]-'a']--;
23. return true;            //其他的所有情况都返回true,都要加入队列
24. }
25. bool bfs()
26. {
27. memset(vis,false,sizeof(vis));
28. queue<node>q;
29. n1.x=begin_x;
30. n1.y=begin_y;
31. q.push(n1);
32. vis[n1.x][n1.y]=true;          //除门之外所有的点都要进行标记
33. while(!q.empty())
34. {
35. n2=q.front();
36. q.pop();
37. if(map[n2.x][n2.y]=='G')   return true;
38. if(map[n2.x][n2.y]>='A'&&map[n2.x][n2.y]<='E')
39. {
40. if(k[map[n2.x][n2.y]-'A']==0)  map[n2.x][n2.y]='.';    //说明钥匙已经全部找到了
41. else
42. {
43. if(q.empty())  return false;
44. else
45. {
46. q.push(n2);     //不进行标记,可以多次走,并且不再从此点进行搜索
47. continue;
48. }
49. }
50. }
51. for(int i=0;i<4;i++)
52. {
53. n1.x=n2.x+dx[i];
54. n1.y=n2.y+dy[i];
55. if(judge(n1.x,n1.y))
56. {
57. q.push(n1);
58. vis[n1.x][n1.y]=true;
59. }
60. }
61. }
62. return false;
63.  
64. }
65. int main()
66. {
67. while(scanf("%d%d",&m,&n)!=EOF&&m+n)
68. {
69. for(int i=0;i<m;i++)
70. scanf("%s",map[i]);
71. memset(k,0,sizeof(k));    //用来保存钥匙的数量
72. for(int i=0;i<m;i++)
73. for(int j=0;j<n;j++)
74. {
75. if(map[i][j]=='S')
76. {
77. begin_x=i;
78. begin_y=j;
79. }
80. if(map[i][j]>='a'&&map[i][j]<='e')  k[map[i][j]-'a']++;
81. }
82. if(bfs())  printf("YES\n");
83. else  printf("NO\n");
84. }
85. return 0;
86. }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值