2021牛客暑期多校训练营8F.Robots

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

第十页

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值