Arab Collegiate Programming Contest 2012G. Archery(求雷达扫描的期望,区间离散化)
来源:互联网 发布:折半查找算法 编辑:程序博客网 时间:2024/06/01 03:58
Last summer you were watching all the matches in the 2012 Olympics in London. One of the interesting sports is archery (it's the game of propelling arrows with the use of a bow to hit a target), but in this problem we are dealing with a new type of archery.
In this new type of archery, the player has arrows that can penetrate any target and can go to infinity (the same arrow may hit more than one target), and there will be a lot of targets around the player everywhere, and the targets may intersect and/or overlap with each others.
From the top view you can model the targets as line segments and the player as a point at the origin (point (0,0) is the origin), also there will be no target which intersects with the player's position.
You are really interested to calculate the expected number of targets this player can penetrate using one arrow, if he will shoot his arrow in a random direction (there are infinite number of different directions, and each direction has the same probability to be used for the random shoot).
For example, the following figure explains the first sample test, where the player is at the origin, and there are two targets T1 with end points (1,5) and (3,3), and T2 with end points (3,5) and (6,2), you can notice that there is a region where the player can shoot an arrow and penetrate the two targets, and there are two regions where he can penetrate only one target, and the last region he will not penetrate any target.
Note that a target can be hit at any point between its 2 end points (inclusive).
The input starts with a line containing one integer N (1 ≤ N ≤ 100) representing the number of targets in the game. Followed by N lines, the ith line contains 4 integers separated by a single space X1 Y1 X2 Y2 (-100 ≤ X1, Y1, X2, Y2 ≤ 100) representing the ith target end points (X1,Y1) and (X2,Y2).
Print on a single line, the expected number of targets the player can penetrate using one arrow. The absolute or relative error in the answer should not exceed 10 - 6.
21 5 3 33 5 6 2
0.206364895
83 0 0 30 3 -3 0-3 0 0 -30 -3 3 03 3 -3 3-3 3 -3 -3-3 -3 3 -33 -3 3 3
2.000000000
地址:http://codeforces.com/gym/100155/problem/G
本场过了5题,就这题有点意义,其他4题都是水题
这题可以形象地这样子描述:
有一个雷达在原点(0,0),有n条线段在平面上,线段不会通过原点,雷达可以在任意角度进行扫描,雷达的电磁波可以射到无限远,穿透所有线段
问,雷达在绕一圈内,能够打到的线段个数的期望。
这题要用正确的区间离散化方法来处理,把每一个端点对应的角度适当离散化,适当建立线段和区间的结构体。
复杂度是O(n*logn),注意数组的范围,有时候可能要开到2*n或者4*n.
(题目有点水,其实n=10^5都可以处理)
代码如下:
//Hello. I'm Peter.#include<cstdio>#include<iostream>#include<sstream>#include<cstring>#include<string>#include<cmath>#include<cstdlib>#include<algorithm>#include<functional>#include<cctype>#include<ctime>#include<stack>#include<queue>#include<vector>#include<set>#include<map>using namespace std;typedef long long ll;typedef long double ld;#define peter cout<<"i am peter"<<endl#define input freopen("data.txt","r",stdin)#define randin srand((unsigned int)time(NULL))#define INT (0x3f3f3f3f)*2#define LL (0x3f3f3f3f3f3f3f3f)*2#define gsize(a) (int)a.size()#define len(a) (int)strlen(a)#define slen(s) (int)s.length()#define pb(a) push_back(a)#define clr(a) memset(a,0,sizeof(a))#define clr_minus1(a) memset(a,-1,sizeof(a))#define clr_INT(a) memset(a,INT,sizeof(a))#define clr_true(a) memset(a,true,sizeof(a))#define clr_false(a) memset(a,false,sizeof(a))#define clr_queue(q) while(!q.empty()) q.pop()#define clr_stack(s) while(!s.empty()) s.pop()#define rep(i, a, b) for (int i = a; i < b; i++)#define dep(i, a, b) for (int i = a; i > b; i--)#define repin(i, a, b) for (int i = a; i <= b; i++)#define depin(i, a, b) for (int i = a; i >= b; i--)#define pi acos(-1.0)#define eps 1e-6#define MOD 1000000007#define MAXN#define N 10010#define Mint dcmp(double x){ if(fabs(x)<eps) return 0; else if(x<0) return -1; else return 1;}struct Segment{ double angle1,angle2;}seg[2*N];int n,num_seg;double xx1,yy1,xx2,yy2,angle1,angle2,ans;double GetAngle(double x,double y){ double res=atan2(y,x); if(res<0) res+=2*pi; return res;}struct Interval{ double angle1,angle2;}interval[2*N];int num_interval;set<double>angleset;set<double>::iterator setit;map<double,int>leftbelong,rightbelong;map<double,int>::iterator mapit;int intervalnum[2*N];int main(){ cin>>n; num_seg=0; repin(i,1,n){ scanf("%lf %lf %lf %lf",&xx1,&yy1,&xx2,&yy2); angle1=GetAngle(xx1,yy1); angle2=GetAngle(xx2,yy2); if(!dcmp(angle1-angle2)) continue; if(dcmp(angle1-angle2)>0) swap(angle1,angle2); double d=angle2-angle1; if(dcmp(d-pi)<0){ int t=++num_seg; seg[t].angle1=angle1; seg[t].angle2=angle2; } else{ int t=++num_seg; seg[t].angle1=angle2; seg[t].angle2=2*pi; t=++num_seg; seg[t].angle1=0.0; seg[t].angle2=angle1; } } angleset.clear(); repin(i,1,num_seg){ angleset.insert(seg[i].angle1); angleset.insert(seg[i].angle2); } int num=0; double last=0.0; num_interval=0; leftbelong.clear(),rightbelong.clear(); for(setit=angleset.begin();setit!=angleset.end();setit++){ num+=1; if(num==1){ last=*setit; continue; } int t=++num_interval; interval[t].angle1=last; interval[t].angle2=*setit; leftbelong[last]=t; rightbelong[*setit]=t; last=*setit; } repin(i,1,num_seg){ int leftbe=leftbelong[seg[i].angle1]; int rightbe=rightbelong[seg[i].angle2]; repin(j,leftbe,rightbe){//这里可以懒操作优化 intervalnum[j]+=1; } } ans=0.0; double d; repin(i,1,num_interval){ d=interval[i].angle2-interval[i].angle1; ans+=intervalnum[i]*(d/(2*pi)); } printf("%.9f\n",ans);}
- Arab Collegiate Programming Contest 2012G. Archery(求雷达扫描的期望,区间离散化)
- Arab Collegiate Programming Contest 2012 解题报告(约等于AK)
- The 2013 Arab Collegiate Programming Contest 题解
- 【Codeforces】2015-2016 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2015) E 线段树+离散化
- German collegiate programming contest 2012 - Ski Jumping
- Galactic Collegiate Programming Contest
- The 12th Zhejiang Provincial Collegiate Programming Contest - G
- 2017 ACM Arabella Collegiate Programming Contest G. Snake Rana GYM101350G
- 2015 China Collegiate Programming Contest
- 2015 ACM Amman Collegiate Programming Contest H.Bridges【边双联通+求树上最长链(树的直径)】
- The 7th Zhejiang Provincial Collegiate Programming Contest->Problem G:G - Wu Xing
- The 11th Zhejiang Provincial Collegiate Programming Contest->Problem G:G - Ternary Calculation
- The 7th Zhejiang Provincial Collegiate Programming Contest->Problem G:G - Wu Xing
- The 11th Zhejiang Provincial Collegiate Programming Contest->Problem G:G - Ternary Calculation
- The 7th Zhejiang Provincial Collegiate Programming Contest - G(Wu Xing)
- Gym 101572G Galactic Collegiate Programming Contest(离线 树状数组)
- 2017-2018 ACM-ICPC, NEERC Problem G Galactic Collegiate Programming Contest(树状数组)
- uva Alberta Collegiate Programming Contest 2011 总结
- 微信消息体加密php版
- JAVA的文件操作【转】
- 用面向对象的Javascript来介绍一下自己
- MySQL新建用户,授权,删除用户,修改密码
- C++ primer 学习笔记第六章
- Arab Collegiate Programming Contest 2012G. Archery(求雷达扫描的期望,区间离散化)
- JAVA的IO处理【转】
- JAVA控制台输入输出方法总结
- C++ Template之编译时断言
- 【UML】类图
- 三种异步访问网络
- Android Fragment+ViewPager:Recursive entry to executePendingTransactions
- unix网络编程学习笔记2
- char *s 和 char s[] 的区别小结