1、一个让人感觉很复杂的 BFS(但是并不很复杂)问题 D: BFS_连连看游戏时间限制: 2 Sec 内存限制: 5 MB提交: 12 解决: 3提交状态 讨论版题目描述大 家都玩过连连看吧!今天我们玩一个类似的游戏。在一个由10*10个小方格组成的矩形里有 n(n#include#includeusing namespace std;int step42=-1,0,1,0,0,-1,0,1;char map1111;int used1111;char ans20;struct hahaint x;int y;int step;friend bool operator b.step;q,temp
2、;int BFS(int x,int y)int x1,y1,i;priority_queueque;memset(used,0,sizeof(used); q.x=x;q.y=y;q.step=0;usedxy=1;que.push(q);while(!que.empty()temp=que.top();que.pop();for(i=0;i=0struct hahachar s50;int val;bool operator 0)return false; q,temp1,temp2;int main()int i,j,cas;scanf(“%d“,for(i=1;iduilie;/cha
3、r s30;scanf(“%d“,/ while(n-)scanf(“%s“,s);if(s0=N)scanf(“%s %d“,q.s,duilie.push(q);elsetemp1=duilie.top();duilie.pop();temp2=duilie.top();duilie.pop();if(temp1.valtemp2.val)printf(“%sn“,temp2.s);temp1.val-=temp2.val;duilie.push(temp1);elseif(temp1.val#include#include#includeusing namespace std;int h
4、ang,lie,val,cnt;char map51005100;struct hahaint x;int y;int val;friend bool operatorb.val;q,temp;struct pint x;int y;a5000+10;int step42=1,0,-1,0,0,1,0,-1,s_x,s_y,e_x,e_y;/把坐标存成了字符型 艾 一天全是低级错误 脑子不清醒int BFS()int i,j,xx,yy,ans=999999999;priority_queueque;q.x=s_x;q.y=s_y;/ 已开始这里写成了 e_y 想打自己啊q.val=0;que
5、.push(q);maps_xs_y=#;while(!que.empty()temp=que.top();que.pop();for(i=0;i=0continue;if(mapxxyy=*)mapxxyy=#;q.x=xx;q.y=yy;q.val=temp.val+val;/这里忘记加 temp.val MLE 了que.push(q);continue;if(mapxxyy=P)for(j=0;j(1,0) 2s:(1,0)-(1,1) 3s:(1,1)-(2,1) 4s:(2,1)-(2,2) 5s:(2,2)-(2,3) 6s:(2,3)-(1,3) 7s:(1,3)-(1,4)
6、8s:FIGHT AT (1,4) 9s:FIGHT AT (1,4)10s:(1,4)-(1,5) 11s:(1,5)-(2,5) 12s:(2,5)-(3,5) 13s:(3,5)-(4,5) FINISH It takes 14 seconds to reach the target position, let me show you the way. 1s:(0,0)-(1,0) 2s:(1,0)-(1,1) 3s:(1,1)-(2,1) 4s:(2,1)-(2,2) 5s:(2,2)-(2,3) 6s:(2,3)-(1,3) 7s:(1,3)-(1,4) 8s:FIGHT AT (1
7、,4) 9s:FIGHT AT (1,4) 10s:(1,4)-(1,5)11s:(1,5)-(2,5) 12s:(2,5)-(3,5) 13s:(3,5)-(4,5) 14s:FIGHT AT (4,5) FINISH God please help our poor hero. FINISH题意:给个二维数组,.可以走,X不可走,1-9代表在此消耗的时间输出记录从(0,0)到(n-1,m-1) 的耗时最小值#include#includeusing namespace std;int m,n;char a105105;int d42=-1,0,0,-1,1,0,0,1;struct hah
8、aint x1;int y1;int ti;friend bool operator b.ti; /重载小于号使得小的先出队列 q,temp;int flag105105;struct xixiint x2;int y2;pre105105;void BFS()int i,x,y,time,x0,y0,xi,yi,j,tm;q.x1=n-1;q.y1=m-1;q.ti=0;if(an-1m-1=48/这个要放进来 每次都要进行从新分配一个队列 不然的话 就会造成上一次的数据无法清空duilie.push(q);while(!duilie.empty()temp=duilie.top();dui
9、lie.pop();if(temp.x1=0 xi=0;yi=0;tm=1;while(prexiyi.x2!=-1)x0=prexiyi.x2;y0=prexiyi.y2;printf(“%ds:(%d,%d)-(%d,%d)n“,tm+,xi,yi,x0,y0);if(ax0y0=48if(axy=48 /定义结构,使用运算符重载,自定义优先级1 struct cmp1 bool operator ()(int /最小值优先 ; struct cmp2 bool operator ()(int /最小值优先 ; struct number2 int x; bool operator que
10、;/采用默认优先级构造队列 priority_queue,cmp1que1;/最小值优先 priority_queue,cmp2que2;/最大值优先 priority_queue,greater que3;/注意“”会被认为错误, /这是右移运算符,所以这里用空格号隔开 priority_queue,less que4;/最大值优先 priority_queueque5; priority_queueque6; int i; for(i=0;ai;i+) que.push(ai); que1.push(ai); que2.push(ai); que3.push(ai); que4.push(
11、ai); for(i=0;num1i.x;i+) que5.push(num1i); for(i=0;num2i.x;i+) que6.push(num2i); printf(“采用默认优先关系:/n(priority_queueque;)/n“); printf(“Queue 0:/n“); while(!que.empty() printf(“%3d“,que.top(); que.pop(); puts(“); puts(“); printf(“采用结构体自定义优先级方式一:/n(priority_queue,cmpque;)/n“); printf(“Queue 1:/n“); whi
12、le(!que1.empty() printf(“%3d“,que1.top(); que1.pop(); puts(“); printf(“Queue 2:/n“); while(!que2.empty() printf(“%3d“,que2.top(); que2.pop(); puts(“); puts(“); printf(“采用头文件/“functional/“内定义优先级:/n(priority_queue,greater/less que;)/n“); printf(“Queue 3:/n“); while(!que3.empty() printf(“%3d“,que3.top(
13、); que3.pop(); puts(“); printf(“Queue 4:/n“); while(!que4.empty() printf(“%3d“,que4.top(); que4.pop(); puts(“); puts(“); printf(“采用结构体自定义优先级方式二:/n(priority_queueque)/n“); printf(“Queue 5:/n“); while(!que5.empty() printf(“%3d“,que5.top(); que5.pop(); puts(“); printf(“Queue 6:/n“); while(!que6.empty()
14、 printf(“%3d“,que6.top(); que6.pop(); puts(“); return 0; /* 运行结果 : 采用默认优先关系: (priority_queueque;) Queue 0: 91 83 72 56 47 36 22 14 10 7 3 采用结构体自定义优先级方式一: (priority_queue,cmpque;) Queue 1: 3 7 10 14 22 36 47 56 72 83 91 Queue 2: 91 83 72 56 47 36 22 14 10 7 3 采用头文件“functional“内定义优先级 : (priority_queue
15、,greater/less que;) Queue 3: 3 7 10 14 22 36 47 56 72 83 91 Queue 4: 91 83 72 56 47 36 22 14 10 7 3 采用结构体自定义优先级方式二: (priority_queueque) Queue 5: 3 7 10 14 22 36 47 56 72 83 91 Queue 6: 91 83 72 56 47 36 22 14 10 7 3 */ 运行结果:采用默认优先关系:(priority_queueque;)Queue 0:91 83 72 56 47 36 22 14 10 7 3采用结构体自定义优
16、先级方式一:(priority_queue,cmpque;)Queue 1:3 7 10 14 22 36 47 56 72 83 91Queue 2:91 83 72 56 47 36 22 14 10 7 3采用头文件“functional“内定义优先级 :(priority_queue,greater/less que;)Queue 3:3 7 10 14 22 36 47 56 72 83 91Queue 4:91 83 72 56 47 36 22 14 10 7 3采用结构体自定义优先级方式二:(priority_queueque)Queue 5:3 7 10 14 22 36 4
17、7 56 72 83 91Queue 6:91 83 72 56 47 36 22 14 10 7 3好了,如果你仔细看完了上面的代码,那么你就可以基本使用优先队列了,下面给出一些我做题中有过的一些应用,希望能给大家带来一些启示1、先来一个我们最近做的题吧,http:/ ,地图上还存在着卫兵,卫兵可以解决掉,但是要另外花费一分钟分析:从“a”出发,此题可以用回溯法进行深搜,但那样做的话,效率还是不能让人满意,但是广搜的话,由于入队后每次出队时,根据地图情况的不同,出队元素所记忆的时间并不是层次递增的,因此使用简单广搜的话,同样需要全部搜索才能找到正确答案。有没有一种方法能让某一步因为遇到士兵而
18、多花时间的结点在队列中向后推迟一层出队呢?答案是肯定的,在这里我们可以用优先队列来实现,总体思想上是,根据时间进行优先性选择,每次都要出队当前队列元素中记录时间最少的出队,而入队处理时,我们可以按顺序对四个方向上的各种情况按正常处理入队就行了,出队顺序由优先队列根据预设优先性自动控制。这样,我们就可以从“a”进行基于优先队列的范围搜索了,并且在第一次抵达有朋友的位置时得到正确结果具体实现代码:cppview plaincopy /*HDU 1242 基于优先队列的范围搜索,16ms dooder*/ #include #include using namespace std; #define
19、M 201 typedef struct p int x,y,t; bool operator a.t;/取时间最少优先 Point; char mapMM; Point start; int n,m; int dir2=1,0,-1,0,0,1,0,-1; int bfs() priority_queueque; Point cur,next; int i; mapstart.xstart.y=#; que.push(start); while(!que.empty() cur=que.top();/由优先队列自动完成出队时间最少的元素 que.pop(); for(i=0;i=n|next
20、.y=m) continue; if(mapnext.xnext.y=#) continue; if(mapnext.xnext.y=r) return next.t; if(mapnext.xnext.y=.) mapnext.xnext.y=#; que.push(next); else if(mapnext.xnext.y=x) mapnext.xnext.y=#; next.t+; que.push(next); return -1; int main() int i,ans; char *p; while(scanf(“%d%d“,i #include #include #inclu
21、de #include using namespace std; #define M 1000050 char strM; int list27; priority_queue,greater que; int main() int ans,sum; int i,a,b,c; while(scanf(“%s“,str),strcmp(str,“END“) memset(list,0,sizeof(list); for(i=0;stri;i+) if(isalpha(stri) liststri-A+; else list26+; sum=i*8;ans=i;c=0; for(i=0;i1)an
22、s=0;/注意只有一种字符的情况 while(que.size()!=1) a=que.top(); que.pop(); b=que.top(); que.pop(); ans+=a+b; que.push(a+b); while(!que.empty()/使用后清空队列 que.pop(); printf(“%d %d %.1f/n“,sum,ans,1.0*sum/ans); return 0; 3、http:/ minheavy 最大值出队,对它的连接结点搜索入队,这样,从出发点开始就可以在到达终点时求出结果,即最大载货物重,实现代码如下:c-sharpview plaincopy /
23、*POJ 2263 16ms dooder*/ #include #include #include using namespace std; #define M 201 typedef struct w int city; int mintons; bool operator que; int min(int a,int b) return ab?b:a; void bfs() Way cur,next; int i; while(!que.empty() cur=que.top(); que.pop(); if(cur.city=to) if(cur.mintonsans) ans=cur
24、.mintons; while(!que.empty() que.pop(); return ; for(i=0;itemp) temp=mapfromi; index=i; cur.city=index; cur.mintons=temp; que.push(cur); bfs(); int main() int k1,k2,tons,t=1; char s131,s231; while(scanf(“%d%d“, while(m-) scanf(“%s%s%d“,s1,s2, for(k1=0;strcmp(s1,citysk1)int len1, len2, len3,flag,hash224224;void DFS( int a,int b,int c )if( len3=c ) flag=1;return ;if( hashab=1 ) /若是该点已经标识表记标帜就代表该点以下的所有路线都接见过,就不须要持续深搜。 return ;hashab=1;if( num1a=num3c )DFS( a+1,b,c+1 );if( num2b=num3c )DFS( a,b+1 ,c+1 ); int main()int T;scanf( “d“ ,for( int i=1; i#includeint map1010;