ZOJ3238 Water Ring(计算几何)
题意:给你一个圆形和很多个矩形,然后要你求圆形的圆周有多少被矩形覆盖。
思路:比赛的时候是有思路的了,不过一直在调别的题,最后剩下30分钟肯定来不及敲。想法是这样的,要是我们可以求出每个矩形覆盖了圆周的哪些区间,我们最后就对这些区间排序然后求区间和就好了,但是问题是怎么知道哪些区间是要的,哪些区间是不要的呢? 首先我们对矩形的四条线段和矩形求交,把所有的交点求出来,然后将交点用atan2转化成极角(我用的区间是[0,2pi]),实际上直接用极角肯定也没问题吧),然后排序,排序之后我们会发现我们要的区间一定是相邻的两个角度的点对应的区间,但是有可能这些区间是不是我们要的,判断的条件就是两个角度的对应的弧段的中点如果在矩形里面的话我们就将这个区间保留。
如此一来就将所有的区间弄了出来,接下来就是求线段的并的总长度了,for一下就好。
但是后来WA了一发,原因是如果圆完全被矩形包含的话,我们解不出交点,会被默认答案是0,所以上面的方法只有在有交点的时候成立,所以判的时候加多一个判是否被完全包含,被完全包含最后直接输出2*pi*r就好,代码写的略长= =
#pragma warning(disable:4996)
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cmath>
#include<string>
#define maxn 150
#define eps 1e-7
using namespace std; const double pi = acos(-1.0); struct Point
{
double x, y;
Point(double xi, double yi) :x(xi), y(yi){}
Point(){}
Point operator + (const Point &b){
return Point(x + b.x, y + b.y);
}
Point operator - (const Point &b){
return Point(x - b.x, y - b.y);
}
double ang(){
double res=atan2(y,x);
if (res < 0) return res + 2*pi;
else return res;
}
Point rot(double ag){
return Point(x*cos(ag) - y*sin(ag), x*sin(ag) + y*cos(ag));
}
}; struct Seg
{
Point st, ed;
Seg(Point sti, Point edi) :st(sti), ed(edi){}
Seg(){}
}; struct Inter
{
double l, r;
Inter(double li, double ri) :l(li), r(ri){}
Inter(){}
bool operator < (const Inter &b) const{
if (l == b.l) return r < b.r;
else return l < b.l;
}
}; int dcmp(double x){
return (x>eps) - (x < -eps);
} double ctr;
int n; vector<double> getInterSection(Seg seg){
vector<double> res;
if (seg.st.x == seg.ed.x){
double xx = seg.st.x;
double y1 = seg.st.y, y2 = seg.ed.y;
if (dcmp(abs(xx) - ctr) > 0) return res;
else if (dcmp(abs(xx) - ctr) == 0){
if (0 >= y1 && 0 <= y2){
res.push_back(Point(xx, 0).ang());
}
}
else{
double dy = sqrt(ctr*ctr - xx*xx);
if (dy >= y1&&dy <= y2){
res.push_back(Point(xx, dy).ang());
}
dy = -dy;
if (dy >= y1&&dy <= y2){
res.push_back(Point(xx, dy).ang());
}
}
}
else{
double yy = seg.st.y;
double x1 = seg.st.x, x2 = seg.ed.x;
if (dcmp(abs(yy) - ctr) > 0) return res;
else if (dcmp(abs(yy) - ctr) == 0){
if (0 >= x1 && 0 <= x2){
res.push_back(Point(0, yy).ang());
}
}
else{
double dx = sqrt(ctr*ctr - yy*yy);
if (dx >= x1&&dx <= x2){
res.push_back(Point(dx, yy).ang());
}
dx = -dx;
if (dx >= x1&&dx <= x2){
res.push_back(Point(dx, yy).ang());
}
}
}
return res;
} bool withinRect(double xx,double yy, double li, double lj, double ri, double rj){
return xx >= li&&xx <= ri&&yy >= lj&&yy <= rj;
} int main()
{
while (cin >> ctr >> n){
double li, lj, ri, rj;
Seg seg;
vector<double> tot;
vector<double> tmp;
vector<Inter> inter; bool flag = false;
for (int i = 0; i < n; i++){
scanf("%lf%lf%lf%lf", &li, &lj, &ri, &rj);
if (flag) continue;
if (li <= -ctr && ctr <= ri && lj <= -ctr&&ctr <= rj){
flag = true; continue;
}
tot.clear();
seg.st = Point(li, lj); seg.ed = Point(li, rj);
tmp = getInterSection(seg);
tot.insert(tot.end(), tmp.begin(), tmp.end()); seg.st = Point(ri, lj); seg.ed = Point(ri, rj);
tmp = getInterSection(seg);
tot.insert(tot.end(), tmp.begin(), tmp.end()); seg.st = Point(li, lj); seg.ed = Point(ri, lj);
tmp = getInterSection(seg);
tot.insert(tot.end(), tmp.begin(), tmp.end()); seg.st = Point(li, rj); seg.ed = Point(ri, rj);
tmp = getInterSection(seg);
tot.insert(tot.end(), tmp.begin(), tmp.end()); sort(tot.begin(), tot.end());
int siz = tot.size();
for (int k = 0; k < siz; k++){
if (dcmp(tot[k] - tot[(k + 1) % siz]) == 0) continue;
Point mid;
if (dcmp(tot[(k + 1) % siz] - tot[k])>0) mid = Point(ctr, 0).rot((tot[k] + tot[(k + 1) % siz]) / 2);
else mid = Point(ctr, 0).rot((tot[k] + tot[(k + 1) % siz]-2*pi) / 2);
if (withinRect(mid.x, mid.y, li, lj, ri, rj)){
if (dcmp(tot[(k + 1) % siz] - tot[k]) >= 0){
inter.push_back(Inter(tot[k], tot[(k + 1) % siz]));
}
else{
inter.push_back(Inter(0, tot[(k+1)%siz]));
inter.push_back(Inter(tot[k % siz], 2 * pi));
}
}
}
}
sort(inter.begin(), inter.end());
double ans = 0;
if (flag) {
printf("%.3lf\n", 2 * pi*ctr); continue;
}
if (inter.size() == 0) {
printf("%.3lf\n", ans); continue;
}
double lt = inter[0].l, rt = inter[0].r;
for (int i = 1; i < inter.size(); i++){
if (inter[i].l <= rt){
rt = max(rt, inter[i].r);
}
else{
ans += rt - lt;
lt = inter[i].l, rt = inter[i].r;
}
}
ans += rt - lt;
printf("%.3lf\n", ans*ctr);
}
return 0;
}
ZOJ3238 Water Ring(计算几何)的更多相关文章
- 【计算几何】Water Testing
Water Testing 题目描述 You just bought a large piece of agricultural land, but you noticed that – accord ...
- 一点公益商城开发系统模式Ring Buffer+
一个队列如果只生产不消费肯定不行的,那么如何及时消费Ring Buffer的数据呢?简单的方案就是当Ring Buffer"写满"的时候一次性将数据"消费"掉. ...
- OpenCASCADE Ring Type Spring Modeling
OpenCASCADE Ring Type Spring Modeling eryar@163.com Abstract. The general method to directly create ...
- 使用Ring Buffer构建高性能的文件写入程序
最近常收到SOD框架的朋友报告的SOD的SQL日志功能报错:文件句柄丢失.经过分析得知,这些朋友使用SOD框架开发了访问量比较大的系统,由于忘记关闭SQL日志功能所以出现了很高频率的日志写入操作,从而 ...
- [AlwaysOn Availability Groups]AlwaysOn Ring Buffers
AlwaysOn Ring Buffers 一些AlwaysOn的诊断信息可以从SQL Server ring buffers.或者从sys.dm_os_ring_buffers.ring buffe ...
- [LeetCode] Pacific Atlantic Water Flow 太平洋大西洋水流
Given an m x n matrix of non-negative integers representing the height of each unit cell in a contin ...
- [LeetCode] Trapping Rain Water II 收集雨水之二
Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevati ...
- [LeetCode] Water and Jug Problem 水罐问题
You are given two jugs with capacities x and y litres. There is an infinite amount of water supply a ...
- [LeetCode] Trapping Rain Water 收集雨水
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
随机推荐
- python解析页面上json字段
一般来说,当我们从一个网页上拿下来数据,就是一个字符串,比如: url_data = urllib2.urlopen(url).readline() 当我们这样得到页面数据,url_data是全部页面 ...
- GRE协议学习与练习
通用路由封装(英语:Generic Routing Encapsulation,缩写为GRE),一种隧道协议,可以在虚拟点对点链路中封装多种网络层协议.由思科系统开发 以下是GRE协议的简单练习 网络 ...
- Datastage数据装载报错:Consumed more than 1000000 bytes looking for record delimiter
使用Datastage装载数据时报错如下图: 使用ds进行数据传输时,出现上述问题,最终找到了问题的原因: 我所使用的数据文件比较大,上传到服务器的时候传了80%就出现服务器存储空间不够,我删除以前的 ...
- SQL0294N 容器已在使用中。 SQLSTATE=42730
在建立数据库后,建立表空间时,出现如下错误: CREATE TABLESPACE TABLESAPCE_NAME PAGESIZE 32K MANAGED BY SYSTEM USING ('E:\D ...
- 鲁棒性是 Robustness
鲁棒性是 Robustness 的音译,是指当系统受到不正常干扰时,是否还能保证主体功能正常运作.可参考 维基百科:http://zh.wikipedia.org/zh/ 鲁棒性 _( 计算机科学 ) ...
- iOS-添加测试设备Identifier
第一步:确认你的设备已经连接 第二步:点击xcode上"Windows"标签,选择"Devices" 第三步:在弹出的左框选择你要添加的设备.在右边框里可以找到 ...
- iOS8 无法设置定位服务
针对iOS8系统,需要在plist文件中添加这两个参数 NSLocationAlwaysUsageDescription = YES NSLocationWhenInUseUsageDescripti ...
- (转)redis 学习笔记(1)-编译、启动、停止
redis 学习笔记(1)-编译.启动.停止 一.下载.编译 redis是以源码方式发行的,先下载源码,然后在linux下编译 1.1 http://www.redis.io/download 先 ...
- R 语言中文乱码问题
R 语言似乎在WINDOWS平台上对中文的支持不是特别好,似乎是3.1.2的一个BUG. 目前我研究出了一个临时解决方案,你可以将代码编写成一个函数,从而在调用的过程中不必如下繁琐: 1. 先将本地语 ...
- P3383: [Usaco2004 Open]Cave Cows 4 洞穴里的牛之四
这个系列总算是做完了,这是我第一次高效率做完四道题,虽然中间有两道水题,但是第一和第四题还是蛮好的,但是只要能想到思路就很快能打完的. 像这道题,刚开始在想能不能用DP?但是苦于不知道怎么实施,后来又 ...