UVA12296 Pieces and Discs
题意
分析
可以看成直线切割多边形,直接维护。
对每个多边形考虑每条边和每个点即可。
时间复杂度?不过\(n,m \leq 20\)这种数据怎么都过了。据说是\(O(n^3)\)的,而且常数也挺小。
一般的比赛估计不会出这种vector套vector的神题。
代码
注意初始化的时候的那个初始长方形的点必须按逆时针顺序来插入。
我写反了,导致调了一晚上。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<ctime>
#include<cstring>
#define rg register
#define il inline
#define co const
template<class T>il T read()
{
rg T data=0;
rg int w=1;
rg char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
{
data=data*10+ch-'0';
ch=getchar();
}
return data*w;
}
template<class T>T read(T&x)
{
return x=read<T>();
}
using namespace std;
typedef long long ll;
co double eps=1e-8;
int dcmp(double x)
{
return fabs(x)<eps?0:(x<0?-1:1);
}
struct Point
{
double x,y;
Point(double x=0,double y=0)
:x(x),y(y){};
};
typedef Point Vector;
typedef vector<Point> Polygon;
Vector operator+(co Vector&A,co Vector&B)
{
return Vector(A.x+B.x,A.y+B.y);
}
Vector operator-(co Vector&A,co Vector&B)
{
return Vector(A.x-B.x,A.y-B.y);
}
Vector operator*(co Vector&A,double p)
{
return Vector(A.x*p,A.y*p);
}
double Dot(co Vector&A,co Vector&B)
{
return A.x*B.x+A.y*B.y;
}
double Cross(co Vector&A,co Vector&B)
{
return A.x*B.y-A.y*B.x;
}
double Length2(co Vector&A)
{
return Dot(A,A);
}
Point LineLineIntersection(co Point&P,co Vector&v,co Point&Q,co Vector&w)
{
Vector u=P-Q;
double t=Cross(w,u)/Cross(v,w);
return P+v*t;
}
bool OnSegment(co Point&p,co Point&a1,co Point&a2)
{
return dcmp(Cross(a1-p,a2-p))==0&&dcmp(Dot(a1-p,a2-p))<0;
}
double PolygonArea(co Polygon&poly)
{
double area=0;
int n=poly.size();
for(int i=1;i<n-1;++i)
area+=Cross(poly[i]-poly[0],poly[(i+1)%n]-poly[0]);
return area/2;
}
Polygon CutPolygon(co Polygon&poly,co Point&A,co Point&B)
{
Polygon newpoly;
int n=poly.size();
for(int i=0;i<n;++i)
{
co Point&C=poly[i];
co Point&D=poly[(i+1)%n];
if(dcmp(Cross(B-A,C-A))>=0)
newpoly.push_back(C);
if(dcmp(Cross(B-A,C-D))!=0)
{
Point ip=LineLineIntersection(A,B-A,C,D-C);
if(OnSegment(ip,C,D))
newpoly.push_back(ip);
}
}
return newpoly;
}
int PointInPolygon(co Point&p,co Polygon&v)
{
int wn=0;
int n=v.size();
for(int i=0;i<n;++i)
{
if(OnSegment(p,v[i],v[(i+1)%n]))
return -1;
int k=dcmp(Cross(v[(i+1)%n]-v[i],p-v[i]));
int d1=dcmp(v[i].y-p.y);
int d2=dcmp(v[(i+1)%n].y-p.y);
if(k>0&&d1<=0&&d2>0)
++wn;
if(k<0&&d2<=0&&d1>0)
--wn;
}
if(wn!=0)
return 1;
return 0;
}
bool InCircle(co Point&p,co Point¢er,double R)
{
return dcmp(Length2(p-center)-R*R)<0;
}
int LineCircleIntersection(co Point&A,co Point&B,co Point&C,double r,double&t1,double&t2)
{
double a=B.x-A.x,
b=A.x-C.x,
c=B.y-A.y,
d=A.y-C.y;
double e=a*a+c*c,
f=2*(a*b+c*d),
g=b*b+d*d-r*r,
delta=f*f-4*e*g;
if(dcmp(delta)<0)
return 0;
if(dcmp(delta)==0)
{
t1=t2=-f/(2*e);
return 1;
}
t1=(-f-sqrt(delta))/(2*e);
t2=(-f+sqrt(delta))/(2*e);
return 2;
}
bool CircleIntersectSegment(co Point&A,co Point&B,co Point&p,double R)
{
double t1,t2;
int c=LineCircleIntersection(A,B,p,R,t1,t2);
if(c<=1)
return 0;
if(dcmp(t1)>0&&dcmp(t1-1)<0)
return 1;
if(dcmp(t2)>0&&dcmp(t2-1)<0)
return 1;
return 0;
}
vector<Polygon> pieces,new_pieces;
void Cut(int x1,int y1,int x2,int y2)
{
new_pieces.clear();
for(int i=0;i<pieces.size();++i)
{
Polygon left=CutPolygon(pieces[i],Point(x1,y1),Point(x2,y2));
Polygon right=CutPolygon(pieces[i],Point(x2,y2),Point(x1,y1));
if(left.size()>=3)
new_pieces.push_back(left);
if(right.size()>=3)
new_pieces.push_back(right);
// cerr<<"left="<<endl;
// for(int j=0;j<left.size();++j)
// cerr<<" "<<left[j].x<<","<<left[j].y;
// cerr<<endl;
// cerr<<"right="<<endl;
// for(int j=0;j<right.size();++j)
// cerr<<" "<<right[j].x<<","<<right[j].y;
// cerr<<endl;
}
pieces=new_pieces;
}
bool DiscIntersectPolygon(co Polygon&poly,co Point&p,double R)
{
if(PointInPolygon(p,poly)!=0)
return 1;
if(InCircle(poly[0],p,R))
return 1;
int n=poly.size();
for(int i=0;i<n;++i)
{
if(CircleIntersectSegment(poly[i],poly[(i+1)%n],p,R))
return 1;
if(InCircle((poly[i]+poly[(i+1)%n])*0.5,p,R))
return 1;
}
return 0;
}
void Query(co Point&p,int R)
{
vector<double>ans;
for(int i=0;i<pieces.size();++i)
if(DiscIntersectPolygon(pieces[i],p,R))
ans.push_back(fabs(PolygonArea(pieces[i])));
printf("%d",ans.size());
sort(ans.begin(),ans.end());
for(int i=0;i<ans.size();++i)
printf(" %.2lf",ans[i]);
printf("\n");
}
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int n,m,L,W;
while(read(n)|read(m)|read(L)|read(W))
{
// cerr<<"n="<<n<<" m="<<m<<" L="<<L<<" W="<<W<<endl;
pieces.clear();
Polygon bbox;
bbox.push_back(Point(0,0)); // edit 1:must follow the order
bbox.push_back(Point(L,0));
bbox.push_back(Point(L,W));
bbox.push_back(Point(0,W));
pieces.push_back(bbox);
for(int i=0;i<n;++i)
{
int x1,y1,x2,y2;
read(x1),read(y1),read(x2),read(y2);
// cerr<<"x1="<<x1<<" y1="<<y1<<" x2="<<x2<<" y2="<<y2<<endl;
Cut(x1,y1,x2,y2);
// for(int i=0;i<pieces.size();++i)
// {
// cerr<<i<<" poly="<<endl;
// for(int j=0;j<pieces[i].size();++j)
// cerr<<" "<<pieces[i][j].x<<","<<pieces[i][j].y;
// cerr<<endl;
// }
}
for(int i=0;i<m;++i)
{
int x,y,R;
read(x),read(y),read(R);
Query(Point(x,y),R);
}
printf("\n");
}
return 0;
}
UVA12296 Pieces and Discs的更多相关文章
- uva 12296 Pieces and Discs
题意: 有个矩形,左下角(0,0),左上角(L,W). 思路: 除了圆盘之外,本题的输入也是个PSLG,因此可以按照前面叙述的算法求出各个区域:只需把线段视为直线,用切割凸多边形的方法 :每次读入线段 ...
- uva 12296 Pieces and Discs (Geometry)
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...
- HITOJ 2662 Pieces Assignment(状压DP)
Pieces Assignment My Tags (Edit) Source : zhouguyue Time limit : 1 sec Memory limit : 64 M S ...
- 1.4.8 拼凑在一起(putting the pieces together)
putting the pieces together 在最高的级别,schema.xml结构如下, <schema> <types> <fields> <u ...
- Pizza pieces
Pizza pieces Description In her trip to Italy, Elizabeth Gilbert made it her duty to eat perfect piz ...
- HDU 4628 Pieces(DP + 状态压缩)
Pieces 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4628 题目大意:给定一个字符串s,如果子序列中有回文,可以一步删除掉它,求把整个序列删除 ...
- Codeforces 328B-Sheldon and Ice Pieces(馋)
B. Sheldon and Ice Pieces time limit per test 1 second memory limit per test 256 megabytes input sta ...
- 2017 NAIPC A:Pieces of Parentheses
my team solve the problem in the contest with similar ideathis is a more deep analysis The main idea ...
- hdu 4628 Pieces 状态压缩dp
Pieces Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total S ...
随机推荐
- Sybase:存储过程中采用临时表存储统计数据
Sybase:存储过程中采用临时表存储统计数据 作用 很有效的提升统计查询速度,对于数据量亿级.千万级多表之间关联查询,非常有效: 使用 --无需定义临时表,直接使用 --自动释放临时表 select ...
- ASP.NET MVC 4.0 中使用NPOI 2.2.0 按模板生成Excel报表
使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写.NPOI是构建在POI 3.x版本之上的,它可以在没有安装Office的情况下对Word/ ...
- JavaWeb XML
1. XML详解 1.1. XML介绍 1.1.1. 什么是XML XML的全称为eXtensible Markup Language,译为可扩展标记语言.XML语法上和HTML比较相似,但HTML中 ...
- nc之netcat端口测试与nmap工具
nc介绍: nc是netcat的简写,有着网络界的瑞士军刀美誉.因为它短小精悍.功能实用,被设计为一个简单.可靠的网络工具,其有Windows和Linux的版本,可通过TCP或UDP协议传输读写数据. ...
- Java的Collection集合的常用方法
boolean add(E e) 添加元素到Collection集合中. boolean addAll(Collection<? extends E> c) 将指定c中的所有元素都添加到此 ...
- Java值传递还是引用传递?
回顾: 在程序设计语言中,将参数传递分为按值调用和按引用调用.按值调用:表示方法接收的是调用者提供的值.而按引用调用表示方法接收的是调用者提供的变量地址.一个方法可以修改传递引用所对应的变量值,而不能 ...
- LeetCode第[46]题(Java):Permutations(求所有全排列) 含扩展——第[47]题Permutations 2
题目:求所有全排列 难度:Medium 题目内容: Given a collection of distinct integers, return all possible permutations. ...
- TimeSpan 结构(struct)
TimeSpan 是结构类型(struct),即值类型,可以通过两个DateTime(struct)之差来获得,如下例子: DateTime departure = new DateTime(2010 ...
- 分享知识-快乐自己:FastDFS详解
在使用fdfs之前,需要对其有一定的了解,这篇文章作为准备篇,将针对fdfs的简介,功能性,使用场景等方面进行介绍 一):起源 淘宝网开放平台技术部资深架构师余庆先生首先回顾了自己在Yahoo工作时的 ...
- CodeForces 385 D.Bear and Floodlight 状压DP
枚举灯的所有可能状态(亮或者不亮)(1<<20)最多可能的情况有1048576种 dp[i]表示 i 状态时灯所能照射到的最远距离(i 的二进制中如果第j位为0,则表示第j个灯不亮,否则就 ...