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