思路好想,细节多的令人发指。。
/* 反着判断:走完每个点=走过的路程=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; }