http://codeforces.com/contest/1365/problem/D
题目大意
给一个n m图,图上有好人 坏人 空地 墙 四种元素。墙不可通过。你可以任意设置墙,问有没有一种设置方法使得好人都可以到n m点 坏人都不行。
做法
遍历整个图,找到所有的G点,从每一个好人点出发,看能否到达终点,路径上如果有相邻的“B”点,则确定为此路不通,否则无法堵住B。这样都遍历完了以后如果存在G点无法到达终点就no否则yes。 中间需要一个小优化。如果一个G点附近有G点并且没有B点,则把这个点变成 ' . ' 这样就省去了一个dfs。不这样做会超时。
代码
#include<bits/stdc++.h> using namespace std; char a[55][55]; int vis[55][55]; int n,m; int dfs(int y,int x){ if(a[y+1][x]=='B'||a[y-1][x]=='B'||a[y][x+1]=='B'||a[y][x-1]=='B'){ return 0; } if(y==n&&x==m){ return 1; } if(a[y+1][x]=='.'||a[y+1][x]=='G'){ if(!vis[y+1][x]){ vis[y+1][x]=1; if(dfs(y+1,x)){ vis[y+1][x]=0; return 1; } } } if(a[y-1][x]=='.'||a[y-1][x]=='G'){ if(!vis[y-1][x]){ vis[y-1][x]=1; if(dfs(y-1,x)){ vis[y-1][x]=0; return 1; } } } if(a[y][x+1]=='.'||a[y][x+1]=='G'){ if(!vis[y][x+1]){ vis[y][x+1]=1; if(dfs(y,x+1)){ vis[y][x+1]=0; return 1; } } } if(a[y][x-1]=='.'||a[y][x-1]=='G'){ if(!vis[y][x-1]){ vis[y][x-1]=1; if(dfs(y,x-1)){ vis[y][x-1]=0; return 1; } } } return 0; } void solve(){ memset(a,0,sizeof(a)); cin>>n>>m; for(int i=1;i<=n;i++){ scanf("%s",a[i]+1); } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(a[i][j]=='G'){ if(a[i+1][j]=='G'||a[i-1][j]=='G'||a[i][j+1]=='G'||a[i][j-1]=='G'){ if(a[i+1][j]!='B'&&a[i-1][j]!='B'&&a[i][j+1]!='B'&&a[i][j-1]!='B'){ a[i][j]='.'; continue; } } memset(vis,0,sizeof(vis)); if(!dfs(i,j)) { cout<<"No"<<endl; return ; } } } } cout<<"Yes"<<endl; } int main(){ int t; cin>>t; while(t--){ solve(); } }