2025牛客多校第四场(持续更新)
"这场多校是不是对标 wf"
B
题意:
给定nxm的01矩阵,其中1代表障碍。以及给定视野范围[y,y+k]
起点(1,1)->终点(1,m)
每次只能往 右 ,上/下走一步
问是否有可能在视野受限的情况下走到当前视野下不知道能否抵达终点的死胡同
思路:
通过分别从起点和终点开始搜索,确定死胡同点
即死胡同是能从起点走到但无法走到终点的点
如果有一个死胡同点满足能够往右走k列,那么就能满足题目给的条件
即一个死胡同深度大于等于k输出yes
由于死胡同点不可能转移到非死胡同点
所以从后往前按列上下dp,满足转移的点都是死胡同点时,如果列不同则该死胡同点深度+1
(PS:不是为啥这题写BFS会TLE啊?被BFS和出题人做局了)
int n,m,k;
const int dx[]={1,-1,0};
const int dy[]={0,0,1};
void dfs(int opt,int x,int y,vector<vector<int>>&vis,vector<vector<char>>&g){
vis[x][y]=1;
for(int i=0;i<3;i++){
int nx=x+dx[i];
int ny;
if(opt==1)ny=y+dy[i];
if(opt==2)ny=y-dy[i];
if(nx<1||nx>n||ny<1||ny>m)continue;
if(vis[nx][ny])continue;
if(g[nx][ny]=='1')continue;
dfs(opt,nx,ny,vis,g);
}
}
void solve(){
cin>>n>>m>>k;
vector<vector<char>>g(n+1,vector<char>(m+1));
vector<vector<int>>vis1(n+1,vector<int>(m+1));
vector<vector<int>>vis2(n+1,vector<int>(m+1));
vector<vector<int>>vis(n+1,vector<int>(m+1));
rep(i,1,n){
string s;cin>>s;
s=" "+s;
rep(j,1,m)g[i][j]=s[j];
}
dfs(1,1,1,vis1,g);
dfs(2,1,m,vis2,g);
rep(i,1,n)rep(j,1,m){
if(!vis1[i][j]&&!vis2[i][j])vis[i][j]=-1;
else if(vis1[i][j]&&!vis2[i][j])vis[i][j]=2;//死胡同
else if(!vis1[i][j]&&vis2[i][j])vis[i][j]=0;
else if(vis1[i][j]&&vis2[i][j])vis[i][j]=1;
}
vector<vector<int>>dp(n+1,vector<int>(m+1,1));
for(int j=m;j>=1;j--){
for(int i=1;i<=n;i++){
if(vis[i][j]==2){
if(j+1<=m&&vis[i][j+1]==2)dp[i][j]=max(dp[i][j],dp[i][j+1]+1);
if(i-1>=1&&vis[i-1][j]==2)dp[i][j]=max(dp[i][j],dp[i-1][j]);
}
}
for(int i=n;i>=1;i--){
if(vis[i][j]==2){
if(i+1<=n&&vis[i+1][j]==2)dp[i][j]=max(dp[i][j],dp[i+1][j]);
}
if(vis[i][j]==2){
if(dp[i][j]>=k){
cout<<"Yes"<<endl;return;
}
}
}
}
cout<<"No"<<endl;
}

浙公网安备 33010602011771号