zoj 3511 Cake Robbery
2012-05-25 21:26
411 查看
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4376
题目大意:一个凸多边形的大蛋糕,切m刀,每刀之间不会相交(端点除外),并且不会出现切在蛋糕的边缘上,求切m刀后边最多的小蛋糕的边数.
题目思路:因为我们求的是边数,所以[b]可以假设这块蛋糕是个正多边形,把每一刀看成线段,我们把线段从小到大排序,然后再去分蛋糕,一刀下去我们把蛋糕分成两部分,把点数少的那一部分的点去掉,因为我们线段不会相交与端点外的其他点,所以,之后切的刀一定不会切在点数少的那一部分的点上,可以自己画几个图切切看.
代码:
[/b]
题目大意:一个凸多边形的大蛋糕,切m刀,每刀之间不会相交(端点除外),并且不会出现切在蛋糕的边缘上,求切m刀后边最多的小蛋糕的边数.
题目思路:因为我们求的是边数,所以[b]可以假设这块蛋糕是个正多边形,把每一刀看成线段,我们把线段从小到大排序,然后再去分蛋糕,一刀下去我们把蛋糕分成两部分,把点数少的那一部分的点去掉,因为我们线段不会相交与端点外的其他点,所以,之后切的刀一定不会切在点数少的那一部分的点上,可以自己画几个图切切看.
代码:
[/b]
#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 ; 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; }
相关文章推荐
- ZOJ 3511 Cake Robbery(成段更新)
- ZOJ3511 Cake Robbery,暴力
- ZOJ 3511 Cake Robbery(线段树)
- zoj 3511 Cake Robbery(线段树)
- ZOJ 3511 Cake Robbery(线段树)
- ZOJ 3511 Cake Robbery
- zoj 3511 Cake Robbery 给一个N个点的环(就当它是个正多边形好了),每次沿着两个点切下去一刀,一共切M刀,刀与刀之间不会交叉,问切完以后边长最多的多边形的边长是多少
- zoj 3511 Cake Robbery
- zoj 3511 Cake Robbery(线段树)
- zoj 3511 Cake Robbery
- ZOJ 3511 不相交切切多边形 线段树求最大边数
- ZOJ3511
- ZOJ 3511 不相交切切多边形 线段树求最大边数
- Zoj 3511 线段树
- zoj1542||poj 1861(简单-MST)
- ZOJ-2886
- ZOJ 3785 What day is that day?(循环节找规律)
- ZOJ2478 Encoding
- ZOJ 3209 Treasure Map DLX入门
- zoj 1940 Dungeon Master