BZOJ3970 WF2013 G Map Tiles
2018-01-16 21:42
204 查看
想象一个框把这个多边形框住,如果知道这个框的左上角的确切位置就能知道答案。
可以发现,这个位置有如下4种情况:
1. 一个顶点在水平线上,一个顶点在竖直线上
2. 一个顶点在水平线上,一个网格点在多边形边上
3. 一个顶点在竖直线上,一个网格点在多边形边上
4. 两个网格点在多边形边上
这样理论的点数有O(102n2) 个,但是点去重后实际数量非常少。
现在的问题是如何快速计算网格数
使用扫描线,对于一块长为1的,可以把里面区间扫一下之类的,拿个二进制数记录是否visit过
可以发现,这个位置有如下4种情况:
1. 一个顶点在水平线上,一个顶点在竖直线上
2. 一个顶点在水平线上,一个网格点在多边形边上
3. 一个顶点在竖直线上,一个网格点在多边形边上
4. 两个网格点在多边形边上
这样理论的点数有O(102n2) 个,但是点去重后实际数量非常少。
现在的问题是如何快速计算网格数
使用扫描线,对于一块长为1的,可以把里面区间扫一下之类的,拿个二进制数记录是否visit过
#include<bits/stdc++.h> #define maxm 500100 #define maxn 110 using namespace std; typedef double ldb; typedef long double Ldb; const ldb eps=1e-7; int inline dcmp(ldb x){ return fabs(x)<eps?0:(x<0?-1:1); } struct point{ ldb x,y; point(){} point(ldb x,ldb y):x(x),y(y){} point operator+(const point& p)const{return point(x+p.x,y+p.y);} point operator+=(const point& p){return *this=*this+p;} point operator-(const point& p)const{return point(x-p.x,y-p.y);} point operator-=(const point& p){return *this=*this-p;} point operator%(const point& p)const{return point(x-floor(x/p.x)*p.x,y-floor(y/p.y)*p.y);} point operator%=(const point& p){return *this=*this%p;} bool operator<(const point& p)const{return x==p.x?x<p.x:y<p.y;} bool operator!=(const point& p)const{return dcmp(x-p.x)||dcmp(y-p.y);} bool operator==(const point& p)const{return !dcmp(x-p.x)&&!dcmp(y-p.y);} void scan(){int a,b;scanf("%d%d",&a,&b);x=a,y=b;} }wxhs[maxm],p[maxn],A[maxn]; int pd(ldb x,ldb L,ldb R){ // printf("<%.3lf,%.3lf,%.3lf,%d>",x,L,R,dcmp(x-L)*dcmp(x-R)>0); return dcmp(x-L)*dcmp(x-R)>0; } int getwei(int l,int r){ return ((1<<r-l+1)-1)<<l; } int getl(ldb a){ return (int)floor(a+eps); } int getr(ldb a){ if(dcmp(floor(a+eps)-a))return (int)floor(a+eps); else return (int)(floor(a+eps))-1; } typedef pair<ldb,ldb> par; int n,w,ans,h,tp,ptr; ldb B[110]; par C[110]; int cal(){ int sum=0,ptr=0,tp=0; for(int i=1;i<=n;++i) B[++ptr]=A[i].x; for(int i=1;i<=11;++i) B[++ptr]=i; sort(B+1,B+ptr+1); int used=0,ptr2=0; for(int i=1;i<=ptr;++i)if(i==1||dcmp(B[ptr2]-B[i]))B[++ptr2]=B[i]; ptr=ptr2; for(int i=1,nxt=1;i<=ptr;++i){ for(int j=1;j<=n;++j)if(dcmp(A[j+1].x-A[j].x)){ if(pd(B[i],A[j].x,A[j+1].x))continue; if(pd(B[i+1],A[j].x,A[j+1].x))continue; ldb y=(Ldb)(A[j+1].y-A[j].y)*(B[i]-A[j].x)/(Ldb)(A[j+1].x-A[j].x)+A[j].y; ldb ny=(Ldb)(A[j+1].y-A[j].y)*(B[i+1]-A[j].x)/(Ldb)(A[j+1].x-A[j].x)+A[j].y; C[++tp]=par(min(ny,y),max(ny,y)); } sort(C+1,C+tp+1); if(tp%2!=0)exit(1); for(int i=1;i<=tp;i+=2) used|=getwei(getl(min(C[i].first,C[i].second)),getr(max(C[i+1].first,C[i+1].second))); if(!dcmp(B[i+1]-nxt)){ sum+=__builtin_popcount(used); nxt++,used=0; } tp=0; } return sum; } int main(){ scanf("%d%d%d",&n,&w,&h); for(int i=1;i<=n;++i)p[i].scan(); p[n+1]=p[1]; //case 1:one in ver line;one in hor line ->n^2 for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) wxhs[++tp]=point(p[i].x,p[j].y); //case 2:one in a ver line;one grid vertex on an edge(not ver) ->n^2*m for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) if(dcmp(p[j].x-p[j+1].x)) for(int k=-10;k<=10;++k){ ldb nx=k*w+p[i].x; if(pd(nx,p[j].x,p[j+1].x))continue; ldb y=(p[j].y-p[j+1].y)*(nx-p[j].x)/(p[j].x-p[j+1].x)+p[j].y; wxhs[++tp]=point(nx,y); } //case 3:one in a hor line;one grid vertex on an edge(not hor) ->n^2*m for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) if(dcmp(p[j].y-p[j+1].y)) for(int k=-10;k<=10;++k){ ldb ny=k*h+p[i].y; if(pd(ny,p[j].y,p[j+1].y))continue; ldb x=(p[j].x-p[j+1].x)*(ny-p[j].y)/(p[j].y-p[j+1].y)+p[j].x; wxhs[++tp]=point(x,ny); } //case 4:both on an edge -> n^2m^2 solve equations for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) for(int k=-10;k<=10;++k) for(int l=-10;l<=10;++l){ ldb A1=p[i+1].y-p[i].y; ldb B1=p[i].x-p[i+1].x; ldb C1=-p[i+1].y*p[i].x+p[i+1].x*p[i].y; ldb A2=p[j+1].y-p[j].y; ldb B2=p[j].x-p[j+1].x; ldb C2=-p[j+1].y*p[j].x+p[j+1].x*p[j].y; if(!dcmp(A1*B2-A2*B1))continue; ldb K=A1*B2-A2*B1; ldb x=(B1*A2*k*w+B1*B2*l*h+B1*C2-B2*C1)/K; ldb y=-(k*w*A1*A2+B2*A1*l*h+C2*A1-C1*A2)/K; if(dcmp(A1*x+B1*y+C1))printf("[%.7lf]",A1*x+B1*y+C1),exit(1); if(dcmp(A2*(x+k*w)+B2*(y+l*h)+C2))exit(2); if(pd(x,p[i].x,p[i+1].x))continue; if(pd(x+k*w,p[j].x,p[j+1].x))continue; wxhs[++tp]=point(x,y); } for(int i=1;i<=tp;++i) wxhs[i]%=point(w,h); sort(wxhs+1,wxhs+tp+1); int ans=1<<30,tp2=0; for(int i=1;i<=tp;++i)if(i==1||(wxhs[tp2]!=wxhs[i])) wxhs[++tp2]=wxhs[i]; tp=tp2; for(int i=1;i<=tp;++i){ ldb x=wxhs[i].x,y=wxhs[i].y; ldb dx=1e20,dy=1e20; for(int j=1;j<=n+1;++j){ A[j].x=(p[j].x-x)/w; A[j].y=(p[j].y-y)/h; dx=min(dx,floor(A[j].x+eps)); dy=min(dy,floor(A[j].y+eps)); } for(int j=1;j<=n+1;++j) A[j].x-=dx,A[j].y-=dy; ans=min(ans,cal()); } printf("%d",ans); }
相关文章推荐
- BZOJ 3969: [WF2013]Low Power
- AutoCAD Map 3D 2013正式版发布
- bzoj3953: [WF2013]Self-Assembly
- Autodesk Infrastructure Map Server(AIMS) 2013开发帮助文档在哪里?离线包下载
- bzoj3969 [WF2013]Low Power
- bzoj 3969: [WF2013]Low Power
- visual studio 2013 c++ 打开code map 功能
- bzoj 3969 WF2013 Low Power [贪心] [二分答案]
- 直接发布DWG到MapGuide/AIMS 2013
- 【 bzoj 3955 】[WF2013]Surely You Congest - 网络流 SPFA
- 2013编程之美-资格赛-传话游戏-编程有问题 艹 理解错题意 不过还好 熟悉了《map》结构
- I - Identifying Map Tiles 2015-2016 Northwestern European Regional Contest (NWERC 2015)
- 读ICCV2013论文<Boolean Map Saliency>
- [BZOJ3969]WF2013 Low Power|二分答案|贪心
- BZOJ3969 [WF2013]Low Power
- TatukGIS Editor使用教程:Map Tiles和GoogleEarth的输出
- 套题:wf2013 (1/8)
- bzoj 3969: [WF2013]Low Power 二分
- Map 3D 2013中的AcMapMap.GroupModified 和AcMapMap.LayerModified 事件的参数变化
- 无需格式转换直接发布DWG图纸到Autodesk Infrastructure Map Server(AIMS) 2013