[Contest20171005]Maze
生活随笔
收集整理的這篇文章主要介紹了
[Contest20171005]Maze
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
考慮一個$N\times M$的網格,每個網格要么是空的,要么是障礙物。整個網格四周都是墻壁(即第$1$行和第$N$行,第$1$列和第$M$列都是墻壁),墻壁有且僅有兩處開口,分別代表起點和終點。起點總是在網格左邊,終點總是在網格右邊。你只能朝$4$個方向移動:上下左右。數據保證從起點到終點至少有一條路徑。
從起點到終點可能有很多條路徑,請找出有多少個網格是所有路徑的必經網格。
?
——妙啊!
轉換一下:
一個網格是必經網格
$\Rightarrow$它變成障礙物之后不能從起點走到終點
$\Rightarrow$它變成障礙物后,從$(1,1)$按八連通走'#'可以走到$(N,M)$
所以我們首先做兩次bfs,分別記錄那些與$(1,1)$或$(N,M)$按八連通可以互達的'#'
然后直接掃一遍,看哪些'.'被可以到達$(1,1)$和$(N,M)$的'#'夾著
然后......就做完了2333
#include<stdio.h> #include<string.h> char s[1010][1010]; bool r[1010][1010][2]; int n,m,qx[1000000],qy[1000000]; const int go[8][2]={{-1,-1},{0,-1},{1,-1},{-1,0},{1,0},{-1,1},{0,1},{1,1}}; bool can(int p,int x,int y){return 1<=x&&x<=n&&1<=y&&y<=m&&s[x][y]=='#'&&!r[x][y][p]; } void bfs(int p,int x,int y){int head,tail,i;head=tail=1;qx[1]=x;qy[1]=y;r[x][y][p]=1;while(head<=tail){x=qx[head];y=qy[head];head++;for(i=0;i<8;i++){if(can(p,x+go[i][0],y+go[i][1])){tail++;r[x+go[i][0]][y+go[i][1]][p]=1;qx[tail]=x+go[i][0];qy[tail]=y+go[i][1];}}} } int main(){int i,j,ii,jj,ans;bool flag;scanf("%d%d",&n,&m);for(i=1;i<=n;i++)scanf("%s",s[i]+1);bfs(0,1,1);bfs(1,n,m);ans=2;for(i=2;i<n;i++){for(j=2;j<m;j++){flag=0;for(ii=0;ii<7;ii++){for(jj=ii+1;jj<8;jj++){if((r[i+go[ii][0]][j+go[ii][1]][0]&&r[i+go[jj][0]][j+go[jj][1]][1])||(r[i+go[ii][0]][j+go[ii][1]][1]&&r[i+go[jj][0]][j+go[jj][1]][0])){ans++;flag=1;break;}}if(flag)break;}}}printf("%d",ans); }轉載于:https://www.cnblogs.com/jefflyy/p/7629114.html
總結
以上是生活随笔為你收集整理的[Contest20171005]Maze的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java.net.URISyntaxEx
- 下一篇: 16线激光雷达配置教程