模拟+细节题——cf1236D

思路好想,细节多的令人发指。。

/*
反着判断:走完每个点=走过的路程=n*m-k
然后暴力判每行每列的目的地
每次走都能使走的范围缩小一行或者一列 
*/
#include<bits/stdc++.h>
#include<vector>
using namespace std;
#define N 200005
#define ll long long 
vector<int>R[N],C[N];//每一行|列内的障碍 
ll tot,n,m,k;

int main(){
    cin>>n>>m>>k;
    for(int i=1;i<=k;i++){
        int r,c;scanf("%d%d",&r,&c);
        R[r].push_back(c);
        C[c].push_back(r);
    }
    
    for(int i=1;i<=n;i++){
        sort(R[i].begin(),R[i].end());
        R[i].erase(unique(R[i].begin(),R[i].end()),R[i].end());
    }
    
    for(int i=1;i<=m;i++){
        sort(C[i].begin(),C[i].end());
        C[i].erase(unique(C[i].begin(),C[i].end()),C[i].end());
    }
    
    tot=1;
    int lx=-1,ly=-1,dir=1,up=0,down=n+1,l=0,r=m+1,x=1,y=1,newx,newy;
    while(1){
        if(dir==1){//向右走
            int pos=lower_bound(R[x].begin(),R[x].end(),y)-R[x].begin(); 
            if(pos==R[x].size())
                newy=r-1;//下面无边界 
            else newy=min(r,R[x][pos])-1;
            tot+=max(0,newy-y);
            dir=2;
            up=x;
            y=newy;
        }
        else if(dir==2){//向下走 
            int pos=lower_bound(C[y].begin(),C[y].end(),x)-C[y].begin();
            if(pos==C[y].size())
                newx=down-1;//下面无边界 
            else newx=min(down,C[y][pos])-1;
            tot+=max(0,newx-x);
            dir=3; 
            r=y;
            x=newx;
        }
        else if(dir==3){//向左走 
            int pos=lower_bound(R[x].begin(),R[x].end(),y)-R[x].begin()-1;        
            if(pos<0)
                newy=l+1;
            else newy=max(l,R[x][pos])+1;
            tot+=max(0,y-newy);
            dir=4;
            down=x;
            y=newy;
        }
        else if(dir==4){//向上走 
            int pos=lower_bound(C[y].begin(),C[y].end(),x)-C[y].begin()-1;    
            if(pos<0)
                newx=up+1;
            else newx=max(up,C[y][pos])+1;
            tot+=max(0,x-newx);
            dir=1;
            l=y;
            x=newx;
        }
        if(x==lx && y==ly)break;//一格都不走表示动不了了 
        lx=x;ly=y;
    }
    
    
//    cout<<tot; 
    if(tot==n*m-k)puts("Yes");
    else puts("No");
    
    return 0;
} 
原文地址:https://www.cnblogs.com/zsben991126/p/11732264.html