HDU 2351 catch him 广度优先搜索

不得不说这道题木让人很蛋疼,本来是一道很简单的广搜题目,但是由于人的位置处于一块连续的区域,所以难度就出来了,关键是防守人的位置怎么存储,这里我是把它存储在一个node类型的vector数组里面,为什么用vector呢,因为之前总是莫名其妙的MLE,不过到后来证明用数组也是不超内存的,应该是我的程序进入了死循环。

ContractedBlock.gif ExpandedBlockStart.gif View Code
  1 #include<iostream>
2 #include<string.h>
3 #include<string>
4 #include<stdio.h>
5 #include<queue>
6 #include<vector>
7 using namespace std;
8 char Map[101][101];
9 int mark[101][101];//设置走过的图的标志数组
10 int H,W;
11 struct node
12 {
13 int x,y;//点的坐标x,y
14 };
15 struct Node
16 {
17 vector<node>dep;//存放防守人的区域(由node点构成)
18 int depth;//描述位置的深度
19 };
20 int X[4]={1,-1,0,0};//X,Y数组表示方向
21 int Y[4]={0,0,1,-1};
22 int Check(int dirX,int dirY,Node N)
23 {
24 int i,len=N.dep.size(),state=0;//state表示check的状态
25 int newx,newy;
26 newx=N.dep[0].x+dirX;
27 newy=N.dep[0].y+dirY;
28 if(mark[newx][newy]==1) return 0;//表不可以移动
29 for(i=0;i<len;i++)
30 {
31 newx=N.dep[i].x+dirX;
32 newy=N.dep[i].y+dirY;
33 if(newx<0 || newx>=H || newy<0 || newy>=W)return 0;//不可以新的newx newy不在图的范围内,所以不可以移动
34 if(Map[newx][newy]=='O')
35 {
36 return 0;
37 }
38 if(Map[newx][newy]=='Q')state=1;//表示新移动到的位置可以catch him
39 }
40 if(state)return 1;//表示抓到四号位,进入这条语句说明新位置没有碰到O,即前锋
41 return 2;//表示可以移动到新位置
42 }
43 int BFS(Node N)
44 {
45 queue<Node>q;
46 int i=0,j=0,len;
47 Node N1;
48 mark[N.dep[0].x][N.dep[0].y]=1;//先将N的位置标志访问过
49 q.push(N);//进队
50 while(!q.empty())
51 {
52 N1=q.front();
53 for(i=0;i<4;i++)
54 {
55 int state=Check(X[i],Y[i],N1);//对每一个方向进行检查可不可以进行移动,或是catch him
56 if(state==0)continue;//不可以移动
57 if(state==1)return N1.depth+1;//catch him 返回当前位置深度再加1
58 if(state==2)//可以进行移动
59 {
60 Node N2;
61 node n;
62 len=N1.dep.size();
63 for(j=0;j<len;j++)//对当前位置内所有点全部进行X[i],Y[i]方向移动
64 {
65 n.x=(N1.dep[j]).x+X[i];
66 n.y=(N1.dep[j]).y+Y[i];
67 N2.dep.push_back(n);
68 }
69 N2.depth=N1.depth+1;//更新深度
70 mark[N2.dep[0].x][N2.dep[0].y]=1;//泥马呀,就是这句标志位移动到了下面注释的那条,就出现了各种错误,上不起啊
71 q.push(N2);
72 }
73 }
74 //mark[N1.dep[0].x][N1.dep[0].y]=1;
75 q.pop();
76 }
77 return 0;
78 }
79 int main()
80 {
81 int i,j,ans;
82 while(scanf("%d %d",&H,&W)!=EOF)
83 {
84 if(H==0 && W==0)break;
85 memset(mark,0,sizeof(mark));
86 node n;
87 Node N;
88 N.depth=0;
89 for(i=0;i<H;i++)
90 {
91 getchar();//读取换行符
92 for(j=0;j<W;j++)
93 {
94 scanf("%c",&Map[i][j]);
95 if(Map[i][j]=='D')
96 {
97 n.x=i;
98 n.y=j;
99 N.dep.push_back(n);
100 }
101 }
102 }
103 //mark[N.dep[0].x][N.dep[0].y]=1;
104 ans=BFS(N);
105 if(ans)
106 {
107 printf("%d\n",ans);continue;
108 }
109 puts("Impossible");
110 }
111 return 0;
112 }



转载于:https://www.cnblogs.com/lonelycatcher/archive/2011/09/23/2186707.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值