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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

luogu P1519 穿越栅栏 Overfencing

發(fā)布時間:2023/12/2 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 luogu P1519 穿越栅栏 Overfencing 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目描述

描述 農(nóng)夫John在外面的田野上搭建了一個巨大的用柵欄圍成的迷宮。幸運(yùn)的是,他在迷宮的邊界上留出了兩段柵欄作為迷宮的出口。更幸運(yùn)的是,他所建造的迷宮是一個“完美的”迷宮:即你能從迷宮中的任意一點(diǎn)找到一條走出迷宮的路。給定迷宮的寬度W(1<=W<=38)及高度H(1<=H<=100)。 2*H+1行,每行2*W+1的字符以下面給出的格式表示一個迷宮。然后計(jì)算從迷宮中最“糟糕”的那一個點(diǎn)走出迷宮所需的步數(shù)(就是從最“糟糕”的一點(diǎn),走出迷宮的最少步數(shù))。(即使從這一點(diǎn)以最優(yōu)的方式走向最靠近的出口,它仍然需要最多的步數(shù))當(dāng)然了,牛們只會水平或垂直地在X或Y軸上移動,他們從來不走對角線。每移動到一個新的方格算作一步(包括移出迷宮的那一步)這是一個W=5,H=3的迷宮:

+-+-+-+-+-+ | | +-+ +-+ + + | | | | + +-+-+ + + | | | +-+ +-+-+-+

如上圖的例子,柵欄的柱子只出現(xiàn)在奇數(shù)行或奇數(shù)列。每個迷宮只有兩個出口。

輸入輸出格式

輸入格式:

?

第一行: W和H(用空格隔開)

第二行至第2 * H + 1行: 每行2 * W + 1個字符表示迷宮

?

輸出格式:

?

輸出一個單獨(dú)的整數(shù),表示能保證牛從迷宮中任意一點(diǎn)走出迷宮的最小步數(shù)。

?

輸入輸出樣例

輸入樣例#1:?
5 3 +-+-+-+-+-+ | | +-+ +-+ + + | | | | + +-+-+ + + | | | +-+ +-+-+-+ 輸出樣例#1:?
9

說明

翻譯來自NOCOW

USACO 2.4

?

剛讀完題,感覺挺簡單啊,不過研究了一下樣例,一臉懵逼,這咋可能?。

經(jīng)過機(jī)房某位 S型 dalao(son)的解讀,哦,so ga si nei,吆西吆西,interisting!!!

再次就借花獻(xiàn)佛了。

關(guān)于的理解題意:

為了便于理解,這里稍微修改一下題目。

奇數(shù)行的柵欄(就是由‘+’和‘-’號組成)將其看做一層類似膜結(jié)構(gòu),一層防護(hù)膜(沒有厚度),穿越不占距離。

然后看偶數(shù)列,這里需要將偶數(shù)列和其兩側(cè)的‘-’看做一個整體,亦可以理解為忽略偶數(shù)列,只考慮奇數(shù)列。

這里拿樣例圖解:

?

結(jié)合上圖,對題意理解就沒什么問題了。

解題剖析:

1.讀入含空格矩陣:

想了半天,試了多種輸入方法,最終貌似只有g(shù)etline(:不會用戳我啊)可以用。

但是在輸入時,需要多輸入一行,并且第一行和第二行會重復(fù),其他沒毛病,最后貌似沒啥大礙。

scanf("%d%d",&w,&h);w=w*2+1;h=h*2+1;for(int i=1;i<=h+1;i++)getline(cin,a[i]);

讀入是這樣的,若有某位dalao明白以上出現(xiàn)的情況,希望討論區(qū)不吝賜教。

2.字符矩陣轉(zhuǎn)換數(shù)字矩陣

在這里定義一個int型map數(shù)組。

map[i][j]表示走到這個點(diǎn)需要消耗的距離(偶數(shù)行為0,奇數(shù)行有空地的話消耗為1)

在字符矩陣中[i][j]這個點(diǎn)為柵欄,不能走,將map[i][j]定義為2.

注意前邊說到,輸入字符時會有一行多余,所以在轉(zhuǎn)換時處理一下。

此部分代碼為:

?

for(int i=2;i<=h+1;i++)for(int j=0;j<w;j++){if(a[i][j]==32){if((i-1)%2==1)map[i-1][j+1]=0;else if((j+1)%2==0)map[i-1][j+1]=1;else map[i-1][j+1]=0;}else map[i-1][j+1]=2;}

?

3.初始化:

ans[i][j]數(shù)組記錄走到 i,j這個點(diǎn)到出口的最近距離,柵欄處直接定義為-1。

void initial() {for(int i=1;i<=h;i++)for(int j=1;j<=w;j++)if(map[i][j]==2)ans[i][j]=-1;else ans[i][j]=214748364; }

?

4.找出出口:

這沒啥好說的,四個邊找出口(注意經(jīng)以上過程出口可能為0,可能為1)。

for(int i=1;i<=w;i++)if(map[1][i]==0||map[1][i]==1)bfs(1,i);for(int i=1;i<=w;i++)if(map[h][i]==0||map[h][i]==1)bfs(h,i);for(int i=1;i<=h;i++)if(map[i][1]==0||map[i][1]==1)bfs(i,1);for(int i=1;i<=h;i++)if(map[i][w]==0||map[i][w]==1)bfs(i,w);

5.大搜索

已經(jīng)處理處每一格的消耗距離,在搜索時,加上就好啦。

兩個出口,需要搜索兩邊所以搜完注意初始化,bool型數(shù)組。

bool vis[N][M]; struct ahah{int x,y; }str,cur; queue <ahah> que; void bfs(int x,int y) {ans[x][y]=0;vis[x][y]=1;str.x=x;str.y=y;que.push(str);while(!que.empty()){cur=que.front();que.pop() ;for(int i=0;i<4;i++){str.x=cur.x+dx[i];str.y=cur.y+dy[i];if(map[str.x][str.y]!=2&&str.x>=1&&str.x<=h&&str.y>=1&&str.y<=w&&!vis[str.x][str.y]){ans[str.x][str.y]=min(ans[cur.x][cur.y]+map[str.x][str.y],ans[str.x][str.y]);vis[str.x][str.y]=1;que.push(str); }}} memset(vis,0,sizeof(vis)); }

6.找出最大值

將ans數(shù)組循環(huán)一遍,找出最大值,輸出即可。

完整代碼:

/*......................... 作者:Manjusaka 時間:2018/7/11 題目:P1519 Overfencing ..........................*/#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <queue> using namespace std; #define N int(100) #define M int(210) int dx[5]={0,0,1,-1},dy[5]={1,-1,0,0}; string a[N]; int w,h,MAX; int x[4],y[4],k; int map[N][M]; int ans[N][M]; void check(); void _scanf(); void initial(); void bfs(int ,int ); void _scanf() {scanf("%d%d",&w,&h);w=w*2+1;h=h*2+1;for(int i=1;i<=h+1;i++)getline(cin,a[i]);for(int i=2;i<=h+1;i++)for(int j=0;j<w;j++){if(a[i][j]==32){if((i-1)%2==1)map[i-1][j+1]=0;else if((j+1)%2==0)map[i-1][j+1]=1;else map[i-1][j+1]=0;}else map[i-1][j+1]=2;} // cout<<"\n";for(int i=1;i<=h;i++){for(int j=1;j<=w;j++){cout<<map[i][j];}cout<<endl;} check(); } void check() {initial(); for(int i=1;i<=w;i++)if(map[1][i]==0||map[1][i]==1)bfs(1,i);for(int i=1;i<=w;i++)if(map[h][i]==0||map[h][i]==1)bfs(h,i);for(int i=1;i<=h;i++)if(map[i][1]==0||map[i][1]==1)bfs(i,1);for(int i=1;i<=h;i++)if(map[i][w]==0||map[i][w]==1)bfs(i,w);for(int i=1;i<=h;i++){cout<<"\n";for(int j=1;j<=w;j++){printf("%3d",ans[i][j]);}} } void initial() {for(int i=1;i<=h;i++)for(int j=1;j<=w;j++)if(map[i][j]==2)ans[i][j]=-1;else ans[i][j]=214748364; } bool vis[N][M]; struct ahah{int x,y; }str,cur; queue <ahah> que; void bfs(int x,int y) {ans[x][y]=0;vis[x][y]=1;str.x=x;str.y=y;que.push(str);while(!que.empty()){cur=que.front();que.pop() ;for(int i=0;i<4;i++){str.x=cur.x+dx[i];str.y=cur.y+dy[i];if(map[str.x][str.y]!=2&&str.x>=1&&str.x<=h&&str.y>=1&&str.y<=w&&!vis[str.x][str.y]){ans[str.x][str.y]=min(ans[cur.x][cur.y]+map[str.x][str.y],ans[str.x][str.y]);vis[str.x][str.y]=1;que.push(str); }}} memset(vis,0,sizeof(vis)); } void _printf() {for(int i=1;i<=h;i++)for(int j=1;j<=w;j++)MAX=max(MAX,ans[i][j]);printf("\n%d",MAX); } int main() {_scanf();_printf(); }

求助大佬!!:

按題目要求來說二位數(shù)組開到100*200應(yīng)該完全可以啊,為什么會比RE,求解釋。

?

轉(zhuǎn)載于:https://www.cnblogs.com/rmy020718/p/9297006.html

總結(jié)

以上是生活随笔為你收集整理的luogu P1519 穿越栅栏 Overfencing的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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