题目地址:http://vjudge.net/problem/UVALive-4851
找规律
案例中的合法点:
注意:A,B也算个餐馆,也要考虑进去
代码如下:
#include <bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(int i=a;i<=(int)(b);++i)
#define REPD(i,a,b) for(int i=a;i>=(int)(b);--i)
const int maxn=60000+10;
#define min3(a,b,c) min(a,min(b,c))
#define max3(a,b,c) max(a,max(b,c))
struct Res
{int x,y;
}res[maxn];
int h1[maxn],h2[maxn];
typedef long long LL;
void Update(int i){REP(dx,0,maxn){int x1=res[i].x+dx,x2=res[i].x-dx;if(x1>=res[1].x&&x2<=res[0].x) break;if(x1<res[1].x){h1[x1]=min(h1[x1],max(res[i].y,2*res[0].y-res[i].y)+dx);h2[x1]=max(h2[x1],min(res[i].y,2*res[0].y-res[i].y)-dx);}if(x2>res[0].x) {h1[x2]=min(h1[x2],max(res[i].y,2*res[0].y-res[i].y)+dx);h2[x2]=max(h2[x2],min(res[i].y,2*res[0].y-res[i].y)-dx);}}
}
int main(int argc, char const *argv[])
{int T,M,n; scanf("%d",&T);while(T--&&scanf("%d%d",&M,&n)==2){REP(i,0,n-1) scanf("%d%d",&res[i].x,&res[i].y),res[i].x++,res[i].y++;if(res[0].x>res[1].x) swap(res[0],res[1]);if(res[1].x-res[0].x==1) {printf("0\n"); continue;}REP(x,res[0].x+1,res[1].x-1) { //确定边界int dx0=x-res[0].x,dx1=res[1].x-x,y=res[0].y;h1[x]=min3(y+dx0,y+dx1,M+1);h2[x]=max3(y-dx0,y-dx1,0);}REP(i,0,n-1) {int x=res[i].x;if(x>res[0].x&&x<res[1].x&&res[i].y<h1[x]&&res[i].y>h2[x]) Update(i); }LL ans=0;REP(x,res[0].x+1,res[1].x-1) if(h1[x]>h2[x]) ans+=h1[x]-h2[x]-1;printf("%lld\n", ans);}return 0;
}