zoj 3511 Cake Robbery

来源:互联网 发布:淘宝怎么图片搜索 编辑:程序博客网 时间:2024/05/02 04:44

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4376

题目大意:一个凸多边形的大蛋糕,切m刀,每刀之间不会相交(端点除外),并且不会出现切在蛋糕的边缘上,求切m刀后边最多的小蛋糕的边数.

题目思路:因为我们求的是边数,所以可以假设这块蛋糕是个正多边形,把每一刀看成线段,我们把线段从小到大排序,然后再去分蛋糕,一刀下去我们把蛋糕分成两部分,把点数少的那一部分的点去掉,因为我们线段不会相交与端点外的其他点,所以,之后切的刀一定不会切在点数少的那一部分的点上,可以自己画几个图切切看.

代码:

#include <stdlib.h>#include <string.h>#include <stdio.h>#include <ctype.h>#include <math.h>#include <time.h>#include <stack>#include <queue>#include <map>#include <set>#include <vector>#include <string>#include <iostream>#include <algorithm>using namespace std;#define ull unsigned __int64#define ll __int64//#define ull unsigned long long//#define ll long long#define son1 New(p.xl,xm,p.yl,ym),(rt<<2)-2#define son2 New(p.xl,xm,min(ym+1,p.yr),p.yr),(rt<<2)-1#define son3 New(min(xm+1,p.xr),p.xr,p.yl,ym),rt<<2#define son4 New(min(xm+1,p.xr),p.xr,min(ym+1,p.yr),p.yr),rt<<2|1#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1#define middle (l+r)>>1#define MOD 1000000007#define esp (1e-8)const int INF=0x3F3F3F3F;const double DINF=10000.00;//const double pi=acos(-1.0);const int N=10010;int n,m,tot;int nn,sum[N<<2],cov[N<<2];struct node{int x,y;void write(){scanf("%d%d",&x,&y);if(x>y) swap(x,y);}bool operator < (const node& p) const {return abs(y-x-nn)>abs(p.y-p.x-nn);}}cut[N];void PushUp(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void Build(int l,int r,int rt){cov[rt]=0;if(l==r){sum[rt]=1;return;}int mid=middle;Build(lson),Build(rson);PushUp(rt);}void PushDown(int rt){if(cov[rt]){int ls=rt<<1,rs=ls|1;sum[ls]=sum[rs]=0;cov[ls]=cov[rs]=1;cov[rt]=0;}}void Update(int l,int r,int rt,int L,int R){if(L<=l && r<=R){sum[rt]=0,cov[rt]=1;return;}PushDown(rt);int mid=middle;if(L<=mid) Update(lson,L,R);if(mid<R) Update(rson,L,R);PushUp(rt);}int Query(int l,int r,int rt,int L,int R){if(L<=l && r<=R) return sum[rt];PushDown(rt);int mid=middle,ret=0;if(L<=mid) ret+=Query(lson,L,R);if(mid<R) ret+=Query(rson,L,R);return ret;}void init(){nn=n>>1;for(int i=0;i<m;i++) cut[i].write();sort(cut,cut+m),Build(1,n,1),tot=0;}void sof(){for(int i=0,j,k;i<m;i++){j=Query(1,n,1,cut[i].x,cut[i].y);k=Query(1,n,1,cut[i].y,n)+Query(1,n,1,1,cut[i].x);if(j<k) tot=max(tot,j),Update(1,n,1,cut[i].x+1,cut[i].y-1);else{tot=max(tot,k);if(cut[i].x>1) Update(1,n,1,1,cut[i].x-1);if(cut[i].y<n) Update(1,n,1,cut[i].y+1,n);}}printf("%d\n",max(tot,sum[1]));}int main(){//freopen("1.in","r",stdin);//freopen("1.out","w",stdout);//int T,cas;scanf("%d",&T);for(cas=1;cas<=T;cas++){while(~scanf("%d%d",&n,&m)) init(),sof();return 0;}