11.17牛客練習賽31 ABC
阿新 • • 發佈:2018-12-22
題目連結:A題
題目大意:就是把 # 看做牆 哪些點無論怎樣移動都不能到達邊界(只能上下左右走),那麼這些點就是可以被標記的點。
#也是可以被標記的點 ,所以 兩者之和就是答案。
思路:我們反著想,從邊界出發,能走到的所有點,計個數,剩下的走不到的就是答案。所以,拿邊界點做DFS就好了。
需要注意的是範圍 題目上說了 m*n<1e6 那麼有可能是 1*1e6 1e6*1 但是二維陣列是沒法開1e6*1e6的 所以用了vector
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<vector> using namespace std; typedef long long ll; const int maxn=1e6+7; struct node { int x1,y1; }q[maxn]; int t=1,w=1; int n,m; int bfs(vector<vector<char> > &a){ while(t!=w){ if(q[t].x1-1>=0&&a[q[t].x1-1][q[t].y1]=='.'){//上 q[w].x1=q[t].x1-1;q[w].y1=q[t].y1;w++;a[q[t].x1-1][q[t].y1]='#'; } if(q[t].y1-1>=0&&a[q[t].x1][q[t].y1-1]=='.'){//左 q[w].x1=q[t].x1;q[w].y1=q[t].y1-1;w++;a[q[t].x1][q[t].y1-1]='#'; } if(q[t].x1+1<n&&a[q[t].x1+1][q[t].y1]=='.'){//下 q[w].x1=q[t].x1+1;q[w].y1=q[t].y1;w++;a[q[t].x1+1][q[t].y1]='#'; } if(q[t].y1+1<m&&a[q[t].x1][q[t].y1+1]=='.'){//右 q[w].x1=q[t].x1;q[w].y1=q[t].y1+1;w++;a[q[t].x1][q[t].y1+1]='#'; } t++; } return w-1; } char ch; int main(){ scanf("%d%d",&n,&m); vector<vector<char> >a(n+3); for(int i=0;i<n;i++){ getchar(); for(int j=0;j<m;j++){ scanf("%c",&ch); a[i].push_back(ch); } } //把邊界上的'.'加進佇列 去做bfs int sum=0; for(int i=0;i<m;i++){//上 if(a[0][i]=='.'){q[w].x1=0;q[w].y1=i;a[q[w].x1][q[w].y1]='#';w++;}; } for(int i=0;i<m;i++){//下 if(a[n-1][i]=='.'){q[w].x1=n-1;q[w].y1=i;a[q[w].x1][q[w].y1]='#';w++;}; } for(int i=0;i<n;i++){//左 if(a[i][0]=='.'){q[w].x1=i;q[w].y1=0;a[q[w].x1][q[w].y1]='#';w++;}; } for(int i=0;i<n;i++){//右 if(a[i][m-1]=='.'){q[w].x1=i;q[w].y1=m-1;a[q[w].x1][q[w].y1]='#';w++;}; } printf("%d\n",n*m-bfs(a)); return 0; }
題目連結:B題
題目大意:
思路: