Robots
链接:https://ac.nowcoder.com/acm/contest/11259/F
大意
存在三种机器人:
1、只能从左往右移动
2、只能从上往下移动
3、既能从左往右又能从上往下移动
图中存在一些障碍,q次询问是否能从给定起点走到终点。
思路
1、2号机器人可以通过前缀和为0(即中途无障碍)求出答案。
3号机器人有些麻烦。
比赛时想到了大致思路但是状态转移想的是用set,爆空间又爆时间,我是伞兵。。。
看到大佬题解才知道用bitset优化,太强了!bitset没怎么写过就没想到,自闭。
思路很简单,离线后每行的起点开始暴力转移状态,看最后终点能不能走到。
b [ i ] [ j ] b[i][j] b[i][j] 表示当前起点行j列能不能走到终点行i列。
CODE
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e2+10;
const int M=5e5+10;
const double eps=1e-6;
struct node
{
int id,y1,x2,y2;
};
int n,m;
char s[N][N];
int dx[N][N],dy[N][N],ans[M];
vector<node>v[N],vec[N];
bitset<N>b[N];
int main()
{
ios::sync_with_stdio(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>(s[i]+1);
for(int j=1;j<=m;j++)
{
dx[i][j]=dx[i][j-1]+(s[i][j]=='1');
dy[i][j]=dy[i-1][j]+(s[i][j]=='1');
}
}
int q;
cin>>q;
for(int i=1;i<=q;i++)
{
int id,x1,y1,x2,y2;
cin>>id>>x1>>y1>>x2>>y2;
if(id==1)
{
if(y1==y2&&x1<=x2&&dy[x2][y2]-dy[x1-1][y1]==0)
ans[i]=1;
}
else if(id==2)
{
if(y1<=y2&&x1==x2&&dx[x2][y2]-dx[x1][y1-1]==0)
ans[i]=1;
}
else
{
if(x1<=x2&&y1<=y2)
v[x1].push_back(node{i,y1,x2,y2});
}
}
for(int i=1;i<=n;i++)
{
for(auto it:v[i])
{
vec[it.x2].push_back(it);
}
for(int j=1;j<=m;j++)
b[j].reset();
for(int j=1;j<=m;j++)
{
if(s[i][j]=='1')
{
b[j].reset();
}
else
{
b[j][j]=1;
b[j]|=b[j-1];
}
}
for(int j=i;j<=n;j++)
{
for(int k=1;k<=m;k++)
{
b[k]|=b[k-1];
if(s[j][k]=='1')
{
b[k].reset();
}
}
for(auto it:vec[j])
{
ans[it.id]=b[it.y2][it.y1];
}
vec[j].clear();
}
}
for(int i=1;i<=q;i++)
{
if(ans[i])
cout<<"yes\n";
else
{
cout<<"no\n";
}
}
return 0;
}