题目大意:有一个M*M的网格,左下角为(0,0),右上角为(M-1,M-1),网格里有两个坐标相同的宾馆A和宾馆B以及n个餐厅,宾馆A和宾馆B各有一个餐厅,现在你打算开一个餐厅,所开餐厅的位置应该满足对于现有的任意的餐厅p,所开的餐厅q应该满足dist(q,A) < dist(p,A)或者dist(q,B) < dist(p,B),注意这里的dist是距离,距离是|x1-x2|+|y1-y2|,问满足的地点数量

解体思路:先排除那些y坐标不再两个宾馆之间的地点,因为这些点都不满足要求。

再考虑一下在这两个宾馆之间的餐馆,如果之间有餐馆,假设这个餐馆的坐标为(x1,y1),宾馆A和宾馆B的坐标为(x2,y2),那么在y1这条轴上的餐馆所能放置的位置就只有在y1和y2之间(对称的先不考虑),这是其中一个限制条件

另一个限制条件是,该竖直轴上能放置餐馆的数量为前一条竖直轴能放置餐馆的数量+1(这里也没有考虑堆成)

从左到右扫描,依次取两个限制条件的最小值,再从右往左扫描

最后的话,再考虑对称性

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxn 60010
int p[maxn];
int main() {
	int test, m, n, x1, x2, y1, y2, x, y;
	scanf("%d", &test);
	while(test--) {
		scanf("%d%d",&m, &n);
		scanf("%d%d%d%d",&x1, &y1, &x2, &y2);
		if(x1 > x2)
			swap(x1,x2);
		for(int i = x1; i <= x2; i++)
			p[i] = m;
		for(int i = 3; i <= n; i++) {
			scanf("%d%d",&x, &y);
			p[x] = min(p[x],abs(y-y1));
		}
		p[x1] = 0;
		for(int i = x1 + 1; i < x2; i++)
			p[i] = min(p[i],p[i-1]+1);
		p[x2] = 0;
		for(int i = x2 - 1; i > x1; i--)
			p[i] = min(p[i],p[i+1]+1);
		long long ans = 0;
		for(int i = x1 + 1; i < x2; i++)
			if(p[i]) {
				ans++;
				ans += min(p[i]-1,y1);
				ans += min(p[i]-1,m-y1-1);	
			}
		printf("%lld\n",ans);
	}
	return 0;
}