CSGO

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 127    Accepted Submission(s): 20

Problem Description

Senior
Pan is crazy about CSGO and she is so skilled. She can kill every enemy
she spots at the same time, even if they are in different positions.
There
are some walls in a map. The locations of enemies are represented by
some points and walls are represented by some line segments in the XY
plane. The position of senior Pan is also described as a point. Senior
Pan can spot an enemy if and only if the segment between them doesn’t
intersect with any wall segment. But if there are other enemies on this
segment, she can kill all of them.
For some given positions, senior
Pan wants to know how many enemies she can kill in these positions. Your
Task is to write a program to figure it out.
 
Input
∙ The input contains multiple test cases, each of them are described below.

The first line contains three integers N, M, Q representing
respectively the number of enemies, the number of walls and the number
of positions senior Pan chooses. For the next N lines, each line contain
two integers X and Y, indicating the location of enemies is (X, Y). The
next M lines, each line contain four integers X1, Y1, X2, Y2,
indicating two endpoints of the wall are (X1, Y1) and (X2, Y2). The last
Q lines, each line contain two integers X and Y, indicating the
location of senior Pan chooses is (X, Y).

You can assume that walls don’t intersect even if in their endpoints,
no enemies have the same location and no enemies are in walls.
∙ N, M <= 10 ^ 4.
∙ Q <= 12.
∙ -10 ^ 6 <= X, Y, X1, Y1, X2, Y2 <= 10 ^ 6
 
Output
For each test case, output "Case #x: " in the first line (without quotes).
For
next Q lines, each line output a number which represents the number of
enemies senior Pan can kill in her i-th chosen location.
 
Sample Input
3 2 1
1 1
2 2
-1 1
0 1 -1 0
2 -2 2 0
0 0
5 4 2
29 -8
19 33
-46 -44
-38 19
9 -20
40 45 38 18
9 -32 -8 46
33 20 35 -19
22 17 -5 40
19 -38
-17 -21
Sample Output
Case #1:
2
Case #2:
3
2
Source
分析:
平面上有一些点和一些线段,保证这些线段互不相交,点不在线段上。
每次问从一个点能看到多少个点。一个点能看到另一点当且仅当这两点连线的线段不和任何一个已知的线段相交。(这里的相交均指非规范相交)
每次以询问点为极点极角排序。线段两端点拆成两个事件,一次出现,一次消失。对于枚举的某一个角度,能否看见当前角度的点仅取决于当前角度上离极点最近的线段,由于保证线段不相交,一条线段在插入时和还存在线段的相对位置是不会改变的,所以可以用set维护,每次先处理当前角度上所有的点是否被线段遮挡就可以了。
复杂度是O(Q(N
+ M)log(N + M))。
下面给出AC代码:
 #include<bits/stdc++.h>

 using namespace std;
const int N = ;
const double eps = 1e-;
const double pi = acos(-1.0);
typedef complex<double> Point; double Det(const Point & a, const Point & b) {return (conj(a) * b).imag();}
double Dot(const Point & a, const Point & b) {return (conj(a) * b).real();}
int sgn(double x) {if(fabs(x) < eps) return ; if(x > eps) return ; return -;} double _ang;
Point ori = (Point) {, };
struct Line :public vector<Point>{
double k;
Line(){}
Line(Point a, Point b){
push_back(a), push_back(b);
k = atan2((b - a).imag(), (b - a).real());
}
};
Point Vec(Line a) {return a[] - a[];}
Point LineIntersection(const Line & a, const Line & b){
double k1 = Det(Vec(a), Vec(b));
double k2 = Det(Vec(b), a[] - b[]);
if(!sgn(k1)){
if(sgn(abs(a[] - b[]) - abs(a[] - b[])) > ) return a[];
else return a[];
}
return a[] + Vec(a) * k2 / k1;
} bool operator < (const Line & a, const Line & b){
Line cur = (Line) {ori, (Point) {cos(_ang), sin(_ang)}};
if(sgn(abs(LineIntersection(a, cur)) - abs(LineIntersection(b, cur))) < ) return ;
return ;
} struct Event{
double k;
int id, typ;
bool operator < (const Event & a) const{
if(sgn(k - a.k)) return k < a.k;
return typ < a.typ;
}
}; double CalcAng(const Point & a) {return atan2(a.imag(), a.real());}
Point p[N];
Line w[N], seg[N];
Event e[N << ]; int q, n, m, tot;
set<Line> s;
int rec[N]; int Calc(int x){
tot = ;
s.clear();
for(int i = ; i <= n; i ++)
e[++ tot] = (Event){CalcAng(p[i] - p[x]), i, }; bool flag = ;
for(int i = ; i <= m; i++){
seg[i] = (Line) {w[i][] - p[x], w[i][] - p[x]};
if(sgn(CalcAng(seg[i][]) - CalcAng(seg[i][])) > ) swap(seg[i][], seg[i][]);
flag = ;
if(sgn(Det(Vec(seg[i]), Point(-, ))) != && sgn(abs(CalcAng(seg[i][]) - CalcAng(seg[i][])) - pi) > ) flag = ;
if(flag) e[++ tot] = (Event) {CalcAng(seg[i][]), i, }, e[++tot] = (Event) {CalcAng(seg[i][]), i, };
else{
e[++ tot] = (Event) {-pi, i, };
e[++ tot] = (Event) {CalcAng(seg[i][]), i, };
e[++ tot] = (Event) {CalcAng(seg[i][]), i, };
e[++ tot] = (Event) {pi, i, };
}
} sort(e + , e + tot + );
int cnt = ;
Point dir, dd;
Line t;
for(int i = ; i <= tot; i ++){
_ang = e[i].k;
if(e[i].typ & ){
dir = (Point) {cos(_ang), sin(_ang)};
if(s.empty() || sgn(abs(LineIntersection(*s.begin(), (Line) {ori, dir})) - abs(p[e[i].id] - p[x])) > ){
cnt ++, rec[cnt] = e[i].id;
}
}
else if(!e[i].typ) s.insert(seg[e[i].id]);
else s.erase(seg[e[i].id]);
} return cnt;
} int Tcase; char fi[] = "pcx.in", fo[] = "pcx.ans";
void Solve(){
printf("Case #%d:\n", ++ Tcase);
double x, y;
Point a, b;
for(int i = ; i <= n; i ++){
scanf("%lf%lf", &x, &y);
p[i] = (Point) {x, y};
}
for(int i = ; i <= m; i ++){
scanf("%lf%lf", &x, &y);
a = (Point) {x, y};
scanf("%lf%lf", &x, &y);
b = (Point) {x, y};
w[i] = (Line) {a, b};
} int ans;
for(int i = ; i <= q; i ++){
scanf("%lf%lf", &x, &y);
p[n + ] = (Point) {x, y};
ans = Calc(n + );
printf("%d\n", ans);
} return;
} int main(){
// freopen("_pc.in", "r", stdin);
// freopen("_pc.ans", "w", stdout);
while(~scanf("%d%d%d", &n, &m, &q))
Solve();
//printf("--->%lf\n", (double) clock() / CLOCKS_PER_SEC);
return ;
}

2017 Multi-University Training Contest - Team 9 1003&&HDU 6163 CSGO【计算几何】的更多相关文章

  1. 2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】

    Colorful Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  2. 2017 Multi-University Training Contest - Team 9 1005&&HDU 6165 FFF at Valentine【强联通缩点+拓扑排序】

    FFF at Valentine Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  3. 2017 Multi-University Training Contest - Team 9 1004&&HDU 6164 Dying Light【数学+模拟】

    Dying Light Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Tot ...

  4. 2017 Multi-University Training Contest - Team 9 1002&&HDU 6162 Ch’s gift【树链部分+线段树】

    Ch’s gift Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  5. 2017 Multi-University Training Contest - Team 9 1001&&HDU 6161 Big binary tree【树形dp+hash】

    Big binary tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  6. 2017 Multi-University Training Contest - Team 1 1006&&HDU 6038 Function【DFS+数论】

    Function Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total ...

  7. 2017 Multi-University Training Contest - Team 1 1002&&HDU 6034 Balala Power!【字符串,贪心+排序】

    Balala Power! Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  8. 2017 Multi-University Training Contest - Team 1 1011&&HDU 6043 KazaQ's Socks【规律题,数学,水】

    KazaQ's Socks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  9. 2017 Multi-University Training Contest - Team 1 1001&&HDU 6033 Add More Zero【签到题,数学,水】

    Add More Zero Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

随机推荐

  1. ios 访问隐私信息 info.plist 中的字段

    1.iOS10相册相机闪退bug: iOS10系统下调用系统相册,相机功能,遇到闪退的情况,描述如下: This app has crashed because it attempted to acc ...

  2. linux集群批量执行命令

    因为工作需要,需要修改集群中机器的配置,一台一台的修改太浪费时间,就想能不能通过自动化脚本批量执行命令,尝试写一个,自己shell不熟悉,写的有点渣渣 if [ "$#" -ne ...

  3. 转:Siri之父:语音交互或将主导未来十年发展

    http://zhinengjiaohu.juhangye.com/201709/weixin_5664458.html Siri之父Adam Cheyer认为,语音交互很可能是未来十年内计算技术的一 ...

  4. ECMAScript中的两种属性

    数据属性 数据属性包含一个数据值的位置.在这个位置可以读取和写入值.数据属性一般用于存储数据数值. 数据属性有4个描述其行为的特征. configurable:true/false,是否可以通过del ...

  5. lesson - 14 linux系统日常管理3

    1. Linux系统服务管理工具ntsysv 类似图形界面管理工具,如果没有该命令使用 yum install -y ntsysv 安装常用服务:crond, iptables, network, s ...

  6. lesson - 10 shell 基础知识

    课程大纲: 1. shell特性 命令历史 history !!  !$  !n  !字符 Tab 键可以补全文件路径或者命令 alias  a=“b”  unalias a 通配符 *匹配零个或多个 ...

  7. ELK开机启动 service文件内容

    为了实现ELK的3部分开机启动,可以添加各项服务对应的service文件,再通过systemctl enable XXX实现ELK所有服务开机启动. Elasticsearch elasticsear ...

  8. 对DataTable(或者DataSet)修改后,提交修改到数据库

    http://blog.csdn.net/nidexuanzhe/article/details/8228832 说明:通常我们在做数据库交互时,并不一定要使用特定的SQL语句来更新数据,.NET F ...

  9. primer漏配问题解决

    在对之前的ITS数据(454数据)做split时,发现有一些reads没有被匹配上,但是barcode能够完全匹配,虽然之后的primer在中间漏了一个碱基,导致后面的碱基全部误匹配,从而导致这条re ...

  10. TypeScript VS JavaScript 深度对比

    TypeScript 和 JavaScript 是目前项目开发中较为流行的两种脚本语言,我们已经熟知 TypeScript 是 JavaScript 的一个超集,但是 TypeScript 与 Jav ...