题目链接https://vjudge.net/contest/306976#problem/F
题目大意:有两个餐厅,A与B,两个的y坐标一样,坐标从0开始到m-1。现在已经有了N个餐厅,让你求出好位置的数量。好位置的定义为,这个位置对于每个现有的餐厅要么离A餐厅更近,要么离B餐厅更近。其中的距离以哈曼顿距离判定。
emmm,注意已有的餐厅包含了A、B餐厅,那么对于没有其他餐厅的时候:
即每一列的一半的数量为:
dis[x1]=0;
for (int i=x1+1; i<x2; i++) dis[i]=min(dis[i],dis[i-1]+1);
dis[x2]=0;
for (int i=x2-1; i>x1; i--) dis[i]=min(dis[i],dis[i+1]+1);
加上其他的餐厅:
for (int i=3; i<=n; i++) {
scanf ("%d%d",&x,&y);
dis[x]=min(abs(y-y1),dis[x]);
}
那么最后的答案就是从x1+1扫描到x2-1的每列的数量:
for (int i=x1+1; i<x2; i++) {//中间的一条线会重复计算,所以先加,之后每列的个数减一
if (dis[i]) {
ans++;
ans+=min(dis[i]-1,y1);//下界
ans+=min(dis[i]-1,m-y1-1);//上界
}
}
以下是AC代码:
#include <bits/stdc++.h>
using namespace std;
const int mac=6e4+10;
int dis[mac];
int main()
{
int t,m,n;
scanf ("%d",&t);
while (t--){
scanf ("%d%d",&m,&n);
int x,y,x1,y2,x2,y1;
scanf ("%d%d%d%d",&x1,&y1,&x2,&y2);
if (x1>x2) swap(x1,x2);
memset(dis,0,sizeof(dis));
for (int i=x1; i<=x2; i++) dis[i]=m;
for (int i=3; i<=n; i++){
scanf ("%d%d",&x,&y);
dis[x]=min(abs(y-y1),dis[x]);
}
dis[x1]=0;
for (int i=x1+1; i<x2; i++) dis[i]=min(dis[i],dis[i-1]+1);
dis[x2]=0;
for (int i=x2-1; i>x1; i--) dis[i]=min(dis[i],dis[i+1]+1);
int ans=0;
for (int i=x1+1; i<x2; i++){
if (dis[i]){
ans++;
ans+=min(dis[i]-1,y1);
ans+=min(dis[i]-1,m-y1-1);
}
}
printf ("%d\n",ans);
}
return 0;
}