日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

广搜(练习4题)

發(fā)布時(shí)間:2023/12/3 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 广搜(练习4题) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

幾道例題還比較簡(jiǎn)單,練習(xí)就卡了比較長(zhǎng)的時(shí)間了(。_。)

所以我會(huì)寫(xiě)一下解題思路了(??д?)
還有博客抽風(fēng)所以代碼里會(huì)有一些奇奇怪怪的東西,無(wú)視就好了qwq。

這幾道題我就按各人認(rèn)為的難易程度來(lái)排序吧QAQ。

第一題.

題意:輸入一個(gè)迷宮,輸出起點(diǎn)到終點(diǎn)的最短路徑。


輸入:

10
0100110100
0001110010
1000000001
1000100011
0000101100
1000001100
1001010011
0000010100
0101010000
1001000001
1 7 10 2

輸出:

14


解題思路:就是走迷宮233。之前做過(guò)的了(⊙o⊙)。

(詳見(jiàn):http://blog.csdn.net/mr_wuyongcong/article/details/78732439 廣搜例題


代碼:

#include<cstdio> using namespace std; int n,head,tail,state[1000001][3],x,y,s,py,px; bool walk[1001][1001]; int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};//移動(dòng)方式 char c; void bfs() {state[1][2]=0;head=0;tail=1;do{head++;//出隊(duì)for (int i=0;i<4;i++){x=state[head][0]+dx[i];//位置y=state[head][1]+dy[i];//位置if (walk[x][y] && x>0 && y>0 && x<=n && y<=n)//是否可以通行{tail++;//入隊(duì)state[tail][2]=state[head][2]+1;state[tail][0]=x;state[tail][1]=y;walk[x][y]=false;//封閉路線if (x==px && y==py)//判斷終點(diǎn){s=state[tail][2];return;}}}}while(head<tail);//判斷結(jié)束 } int main() {scanf("%d\n",&n);for (int i=1;i<=n;i++){for (int j=1;j<=n;j++){c=getchar();if (c=='0') walk[i][j]=true;}c=getchar();} scanf("%d%d%d%d",&state[1][0],&state[1][1],&px,&py); //輸入不解釋bfs();//廣搜不解釋printf("%d",s);//輸出不解釋//就是那么任性QAQ }


第二題:細(xì)胞問(wèn)題(水題)

題目大意:一矩形陣列由數(shù)字0到9組成,數(shù)字1到9代表細(xì)胞,細(xì)胞的定義為沿細(xì)胞數(shù)字上下左右還是細(xì)胞數(shù)字則為同一細(xì)胞,求給定矩形陣列的細(xì)胞個(gè)數(shù)。


輸入:

4 10
0234500067
1034560500
2045600671
0000000089
輸出:

4


解題思路:這道題剛開(kāi)始做了半天從一個(gè)開(kāi)始搜。后來(lái)突然頓悟,為什么不能從多個(gè)位置開(kāi)始搜>(@_@)<。于是就輕輕松松的搞定了233。


代碼:

#include<cstdio> using namespace std; int n,m,s,head,tail,state[2401][2]; int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};//細(xì)胞拓展方向 int a[61][61]; char c; void bfs(int x,int y) {head=0;tail=1;state[1][0]=x;state[1][1]=y;do{head++;//出隊(duì)for (int i=0;i<4;i++){x=state[head][0]+dx[i];y=state[head][1]+dy[i];if(a[x][y] && x>0 && x<=m && y>0 && y<=n)//如果這里是細(xì)胞則往這邊拓展{tail++;//入隊(duì)a[x][y]=false;//封閉該位置細(xì)胞state[tail][0]=x;state[tail][1]=y;}}}while (head<tail); } int main() {scanf("%d%d\n",&m,&n); for (int i=1;i<=m;i++){for (int j=1;j<=n;j++){c=getchar();if (c!='0') a[i][j]=true;}c=getchar();}//輸入不解釋 for (int i=1;i<=m;i++)for (int j=1;j<=n;j++)//將所有的細(xì)胞枚舉一遍{if(a[i][j])//當(dāng)該處有細(xì)胞時(shí)數(shù)量可以加了{(lán)bfs(i,j);//封閉該位置鏈接的細(xì)胞s++;//數(shù)量加1}}printf("%d",s);//輸出 }

第三題:最小轉(zhuǎn)彎路徑(難度開(kāi)始加大了)

題意:給出一個(gè)地圖,求起點(diǎn)到終點(diǎn)要轉(zhuǎn)的最少?gòu)潝?shù)。


輸入:

5 7
1 0 0 0 0 1 0
0 0 1 0 1 0 0 ?
0 0 0 0 1 0 1 ?
0 1 1 0 0 0 0 ?
0 0 0 0 1 1 0?
1 3 1 7?

輸出:

5

附圖:


解題思路:

最小轉(zhuǎn)彎,不是最少步數(shù)。做法比較簡(jiǎn)單,不過(guò)是把拓展方式從4個(gè)方向一個(gè)格改成從4個(gè)方向撞到墻為止的一次性拓展完。(用老師的說(shuō)法就是代價(jià)相同)

不過(guò)注意:封路和墻不要混為一談。因?yàn)樗亲驳綁Σ磐V雇卣?#xff0c;而碰到已經(jīng)被走過(guò)的路只不過(guò)是不入隊(duì)而不是不繼續(xù)拓展。(被卡了好一會(huì)qAq)


貼代碼時(shí)間:

#include<cstdio> using namespace std; int head,tail,n,m,state[10001][3],c,s,x,y,qx,qy; bool ok[101][101],a[101][101]; int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};//拓展方向 void bfs() {head=0;tail=1;do{head++;//出隊(duì)for (int i=0;i<4;i++)//4個(gè)方向{x=state[head][0];y=state[head][1];int j=1;while (!a[x+dx[i]*j][y+dy[i]*j] && x+dx[i]*j<=n && y+dy[i]*j<=m && x+dx[i]*j>0 && y+dy[i]*j>0)//如果碰到墻或邊緣就結(jié)束拓展{if (!ok[x+dx[i]*j][y+dy[i]*j])//如果已經(jīng)走過(guò)的路線就不入隊(duì){tail++;//入隊(duì)state[tail][0]=x+dx[i]*j;state[tail][1]=y+dy[i]*j;//儲(chǔ)存位置state[tail][2]=state[head][2]+1;//儲(chǔ)存轉(zhuǎn)彎數(shù)ok[x+dx[i]*j][y+dy[i]*j]=true;//已經(jīng)走過(guò)該地if (x+dx[i]*j==qx && y+dy[i]*j==qy)//結(jié)束判斷{s=state[tail][2];return;}}j++;//下一個(gè)拓展}}}while(head<tail);//空隊(duì)退出 } int main() {scanf("%d%d\n",&n,&m); for (int i=1;i<=n;i++){for (int j=1;j<=m;j++){scanf("%d",&c);if (c!=0) a[i][j]=true;}}scanf("%d%d%d%d",&state[1][0],&state[1][1],&qx,&qy);//輸入不解釋bfs();//函數(shù)不解釋printf("%d",s-1);//輸出不解釋 }
最后的壓軸題:麻將游戲

在一種"麻將"游戲中,游戲是在一個(gè)有W*H格子的矩形平板上進(jìn)行的。每個(gè)格子可以放置一個(gè)麻將牌,也可以不放(如圖所示)。玩家的目標(biāo)是將平板上的所有可通過(guò)一條路徑相連的兩張相同的麻將牌,從平板上移去。最后如果能將所有牌移出平板,則算過(guò)關(guān)。
  這個(gè)游戲中的一個(gè)關(guān)鍵問(wèn)題是:兩張牌之間是否可以被一條路徑所連接,該路徑滿足以下兩個(gè)特性:
  1. 它由若干條線段組成,每條線段要么是水平方向,要么是垂直方向。
  2. 這條路徑不能橫穿任何一個(gè)麻將牌 (但允許路徑暫時(shí)離開(kāi)平板)。
  這是一個(gè)例子:


  在(1,3)的牌和在(4, 4)的牌可以被連接。(2, 3)和(3, 4)不能被連接。
  你的任務(wù)是編一個(gè)程序,檢測(cè)兩張牌是否能被一條符合以上規(guī)定的路徑所連接。?


輸入:輸入文件的第一行有兩個(gè)整數(shù)w,h (1<=w,h<=75),表示平板的寬和高。接下來(lái)h行描述平板信息,每行包含w個(gè)字符,如果某格子有一張牌,則這個(gè)格子上有個(gè)'X',否則是一個(gè)空格。平板上最左上角格子的坐標(biāo)為(1,1),最右下角格子的坐標(biāo)為(w,h)。接下來(lái)的若干行,每行有四個(gè)數(shù)x1, y1, x2, y2 ,且滿足1<=x1,x2<=w,1<=y1,y2<=h,表示兩張牌的坐標(biāo)(這兩張牌的坐標(biāo)總是不同的)。如果出現(xiàn)連續(xù)四個(gè)0,則表示輸入結(jié)束。

5 4
XXXXX
X ? X
XXX X
?XXX?
2 3 5 3
1 3 4 4
2 3 3 4
0 0 0 0


輸出:

輸出文件中,對(duì)于每一對(duì)牌輸出占一行,為連接這一對(duì)牌的路徑最少包含的線段數(shù)。如果不存在路徑則輸出0。

4

3

0


解題思路:這道題卡了挺久的,近5個(gè)小時(shí)才做出來(lái)。這道題一看就是第三題的升級(jí)版,只要注意可以走外圍和每次把封路還原就Ok了o(>﹏<)o


終極代碼時(shí)間:

#include<cstdio> using namespace std; int head,tail,state[5930][3],n,m,s,x1,x2,y1,y2; bool a[77][77],walk[77][77]; int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};//4個(gè)方向 char c; void bfs(int x,int y,int px,int py) //計(jì)算從(x,y)到(px,py)的最小轉(zhuǎn)彎數(shù) //這里不講了,詳見(jiàn)第3題 {head=0;tail=1;state[1][0]=x;state[1][1]=y;state[1][2]=0;do{head++;for (int i=0;i<4;i++){x=state[head][0];y=state[head][1];int j=1;while (!a[x+dx[i]*j][y+dy[i]*j] && x+dx[i]*j<=n+1 && y+dy[i]*j<=m+1 && x+dx[i]*j>=0 && y+dy[i]*j>=0){if (!walk[x+dx[i]*j][y+dy[i]*j]){tail++;state[tail][0]=x+dx[i]*j;state[tail][1]=y+dy[i]*j;state[tail][2]=state[head][2]+1;walk[x+dx[i]*j][y+dy[i]*j]=true;if (x+dx[i]*j==px && y+dy[i]*j==py){s=state[tail][2];return;}}j++;}}}while(head<tail); } int main() {scanf("%d%d",&m,&n);//輸入,注意是反過(guò)來(lái)的c=getchar();//讀第一行的換行符for (int i=1;i<=n;i++){int j=0;while ((c=getchar())!='\n'){j++;if (c=='X') a[i][j]=true;//處理可否通行}} x1=1;while (x1!=0 || y1!=0 || x2!=0 || y2!=0)//如果都為零就退出{scanf("%d%d%d%d",&y1,&x1,&y2,&x2);//輸入,注意是反過(guò)來(lái)的if (x1!=0 && y1!=0 && x2!=0 && y2!=0)//如果都不為0{for (int i=0;i<=n+1;i++)for (int j=0;j<=m+1;j++) {walk[i][j]=false;}//還原封路s=0;//還原a[x2][y2]=false;//解掉終點(diǎn)的封鎖bfs(x1,y1,x2,y2);//求a[x2][y2]=true;//打開(kāi)終點(diǎn)的封鎖printf("%d\n",s);}} }

好了,廣搜題目就那么多。↖(^ω^)↗

總結(jié)

以上是生活随笔為你收集整理的广搜(练习4题)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。