题解:P10275 [USACO24OPEN] Walking Along a Fence B
发现 dis。
要求出两个点之间的距离,可以先找到对应的栅栏的起始点,然后计算它们之间的距离 dis[y]-dis[x](如果
最后只需要输出
#include<bits/stdc++.h>
#define endl "\n"
using namespace std;
int cald(int xa,int ya,int xb,int yb){
return abs(xa-xb+ya-yb);
}
struct point{
int x,y,n;
}pt[200005],lp[1005][1005];
int dis[200005];
int main(){
ios::sync_with_stdio(0);cin.tie(0);
int n,p;cin>>n>>p;
for(int i=1;i<=p;i++){
cin>>pt[i].x>>pt[i].y;
pt[i].n=i;
}
pt[0]=pt[p];
for(int i=1;i<=p;i++){
int lx=pt[i-1].x,ly=pt[i-1].y,nx=pt[i].x,ny=pt[i].y;
dis[i]=dis[i-1]+cald(lx,ly,nx,ny);
if(lx==nx){
if(ly<ny){
for(int j=ly;j<ny;j++){
lp[nx][j].x=lx;
lp[nx][j].y=ly;
lp[nx][j].n=i-1;
}
}else{
for(int j=ly;j>ny;j--){
lp[nx][j].x=lx;
lp[nx][j].y=ly;
lp[nx][j].n=i-1;
}
}
}else{
if(lx<nx){
for(int j=lx;j<nx;j++){
lp[j][ny].x=lx;
lp[j][ny].y=ly;
lp[j][ny].n=i-1;
}
}else{
for(int j=lx;j>nx;j--){
lp[j][ny].x=lx;
lp[j][ny].y=ly;
lp[j][ny].n=i-1;
}
}
}
}
for(int i=1;i<=n;i++){
int xa,xb,ya,yb;cin>>xa>>ya>>xb>>yb;
int lxa=lp[xa][ya].x,lxb=lp[xb][yb].x,lya=lp[xa][ya].y,lyb=lp[xb][yb].y;
int lna=lp[xa][ya].n,lnb=lp[xb][yb].n;
if(lna>lnb){
swap(xa,xb);
swap(ya,yb);
swap(lxa,lxb);
swap(lya,lyb);
swap(lna,lnb);
}
int dis1=dis[lnb]-dis[lna];
int disa=cald(xa,ya,lxa,lya);
int disb=cald(xb,yb,lxb,lyb);
int ans=abs(dis1-disa+disb);
cout<<min(ans,dis[p]-ans)<<endl;
}
return 0;
}