zoukankan      html  css  js  c++  java
  • [CF1236D] Alice and the Doll

    [CF1236D] Alice and the Doll

    Description

    (N imes M)网格,有 (K) 个格子里有障碍物。每次经过一个格子的时候只能直走或者右转一次。初态在 ((1,1)) 格子向上。求是否存在一条路径经过所有无障碍格子恰好一次。

    Solution

    最优的走法是遇到障碍或者边界就右转,否则直走。

    走过一排格子相当于挪动边界线。

    这两个结论仔细品味起来很挺有深度的。

    然后暴力模拟就可以了,找障碍物的过程可以用 set 优化。

    这题的坐标系好像有点奇怪,SB的我就这么搞反坐标WA了一发。然后忘记开longlong又WA了一发。

    Code
    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    const int N = 100005;
    
    int n,m,k,t1,t2,t3,t4,lx,ly,ux,uy,dir,ans=1;
    set <int> sx[N],sy[N];
    
    int FindIncX(int x,int y)
    {
        return min(ux,*sy[y].lower_bound(x));
    }
    
    int FindDecX(int x,int y)
    {
        return max(lx,*(--sy[y].lower_bound(x)));
    }
    
    int FindIncY(int x,int y)
    {
        return min(uy,*sx[x].lower_bound(y));
    }
    
    int FindDecY(int x,int y)
    {
        return max(ly,*(--sx[x].lower_bound(y)));
    }
    
    signed main()
    {
        cin>>n>>m>>k;
        lx=0;
        ly=0;
        ux=n+1;
        uy=m+1;
        for(int i=1; i<=m; i++)
        {
            sy[i].insert(0);
            sy[i].insert(n+1);
        }
        for(int i=1; i<=n; i++)
        {
            sx[i].insert(0);
            sx[i].insert(m+1);
        }
        for(int i=1; i<=k; i++)
        {
            cin>>t1>>t2;
            sx[t1].insert(t2);
            sy[t2].insert(t1);
        }
        dir=0;
        int x=1,y=1;
        while(true)
        {
            int nx,ny;
            switch(dir)
            {
            case 0:
                nx=x;
                ny=FindIncY(x,y)-1;
                break;
            case 1:
                ny=y;
                nx=FindIncX(x,y)-1;
                break;
            case 2:
                nx=x;
                ny=FindDecY(x,y)+1;
                break;
            case 3:
                ny=y;
                nx=FindDecX(x,y)+1;
                break;
            }
            if(x==nx && y==ny)
            {
                dir=(dir+1)%4;
                switch(dir)
                {
                case 0:
                    nx=x;
                    ny=FindIncY(x,y)-1;
                    break;
                case 1:
                    ny=y;
                    nx=FindIncX(x,y)-1;
                    break;
                case 2:
                    nx=x;
                    ny=FindDecY(x,y)+1;
                    break;
                case 3:
                    ny=y;
                    nx=FindDecX(x,y)+1;
                    break;
                }
                if(x==nx && y==ny)
                    break;
            }
            ans += abs(nx-x) + abs(ny-y);
            switch(dir)
            {
            case 0:
                lx=max(lx,nx);
                break;
            case 1:
                uy=min(uy,ny);
                break;
            case 2:
                ux=min(ux,nx);
                break;
            case 3:
                ly=max(ly,ny);
                break;
            }
            x=nx;
            y=ny;
        }
        //cout<<ans<<endl;
        if(ans==n*m-k)
        {
            cout<<"Yes"<<endl;
        }
        else
        {
            cout<<"No"<<endl;
        }
    }
    
    
  • 相关阅读:
    Thread.currentThread().getName() ,对象实例.getName() 和 this.getName()区别
    CentOS7.7 yum安装新版git
    CentOS使用epel安装不同版本php-fpm
    ubuntu16.04安装mysql5.6
    阿里云Confluence无法发送邮件修复
    windowserver 2012安装openssh
    linux增加history时间戳
    SQL Server 2008R2各个版本,如何查看是否激活,剩余可用日期?
    nginx增加访问验证
    mysql5.6和5.7的权限密码设置
  • 原文地址:https://www.cnblogs.com/mollnn/p/11721890.html
Copyright © 2011-2022 走看看