2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 GSM Base Station Identification (点在多边形内模板)
Posted 抓不住Jerry的Tom
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 GSM Base Station Identification (点在多边形内模板)相关的知识,希望对你有一定的参考价值。
In the Personal Communication Service systems such as GSM (Global System for Mobile Communications), there are typically a number of base stations spreading around the service area. The base stations are arranged in a cellular structure, as shown in the following figure. In each cell, the base station is located at the center of the cell.
For convenience, each cell is denoted by [ii, jj]. The cell covers the origin is denoted by [00, 00]. The cell in the east of [00, 00] is denoted by [11, 00]. The cell in the west of [00, 00] is denoted by [-1?1, 00]. The cell in the northeast of [00, 00] is denoted by [00, 11]. The cell in the southwest of [00, 00] is denoted by [00, -1?1]. This notation can be easily generalized, as shown in the above figure.
Now the question is as follows. We have a service area represented by a Euclidean plane (i.e., x-yx?y plane). Each unit is 11 Km. For example, point (55, 00) in the plane means the location at a distance of 55 Km to the east of the origin. We assume that there are totally 400400 cells, denoted by [ii, jj], i\ =\ -9 \ ... \ 10i = ?9 ... 10, j\ =\ -9\ ... \ 10j = ?9 ... 10. The base station of cell [00, 00] is located at the origin of the Euclidean plane. Each cell has a radius of RR = 55 Km, as shown in the following figure.
You are given an input (xx, yy), which indicates a mobile phone’s location. And you need to determine the cell [ii, jj] that covers this mobile phone and can serve this phone call.
For example, given a location (1010, 00), your program needs to output the cell [11, 00], which can cover this location. Specifically, the input and output are:
- input = (xx, yy). hhis is a location on the Euclidean plane. This value will not exceed the service area covered by the 400400 cells. That is, you do not need to handle the exceptional case that the input is out of the boundary of the service area.
- output = [ii, jj]. One of the 400400 cells that covers location [ii, jj]
Input Format
A list of 1010 locations.
Output Format
A list of 1010 cells covering the above 1010 locations in the correct order.
Please be reminded that there exist a space between coordinates.
样例输入
1 0
0 15
2 0
13 7
5 5
10 15
25 15
-13 -8
12 -7
-10 0
样例输出
[0,0], [-1,2], [0,0], [1,1], [0,1], [0,2], [2,2], [-1,-1], [2,-1], [-1,0]
1 #include <bits/stdc++.h> 2 using namespace std; 3 const double inf = 1000000000.0; 4 const double ESP = 1e-5; 5 const int MAX_N = 1000; 6 const double o = 2.5*sqrt(3.0); 7 struct Point 8 { 9 double x, y; 10 }; 11 struct LineSegment 12 { 13 Point pt1, pt2; 14 }; 15 typedef vector<Point> Polygon; 16 Polygon pp; 17 double Multiply(Point p1, Point p2, Point p0) 18 { 19 return ( (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y) ); 20 } 21 bool IsOnline(Point point, LineSegment line) 22 { 23 return( ( fabs(Multiply(line.pt1, line.pt2, point)) < ESP ) && 24 ( ( point.x - line.pt1.x ) * ( point.x - line.pt2.x ) <= 0 ) && 25 ( ( point.y - line.pt1.y ) * ( point.y - line.pt2.y ) <= 0 ) ); 26 } 27 bool Intersect(LineSegment L1, LineSegment L2) 28 { 29 return( (max(L1.pt1.x, L1.pt2.x) >= min(L2.pt1.x, L2.pt2.x)) && 30 (max(L2.pt1.x, L2.pt2.x) >= min(L1.pt1.x, L1.pt2.x)) && 31 (max(L1.pt1.y, L1.pt2.y) >= min(L2.pt1.y, L2.pt2.y)) && 32 (max(L2.pt1.y, L2.pt2.y) >= min(L1.pt1.y, L1.pt2.y)) && 33 (Multiply(L2.pt1, L1.pt2, L1.pt1) * Multiply(L1.pt2, L2.pt2, L1.pt1) >= 0) && 34 (Multiply(L1.pt1, L2.pt2, L2.pt1) * Multiply(L2.pt2, L1.pt2, L2.pt1) >= 0) 35 ); 36 } 37 /* 射线法判断点q与多边形polygon的位置关系,要求polygon为简单多边形,顶点逆时针排列 38 如果点在多边形内: 返回0 39 如果点在多边形边上: 返回1 40 如果点在多边形外: 返回2 41 */ 42 bool InPolygon(const Polygon& polygon, Point point) 43 { 44 int n = polygon.size(); 45 int count = 0; 46 LineSegment line; 47 line.pt1 = point; 48 line.pt2.y = point.y; 49 line.pt2.x = - inf; 50 51 for( int i = 0; i < n; i++ ) 52 { 53 LineSegment side; 54 side.pt1 = polygon[i]; 55 side.pt2 = polygon[(i + 1) % n]; 56 57 if( IsOnline(point, side) ) 58 { 59 return 1; 60 } 61 62 if( fabs(side.pt1.y - side.pt2.y) < ESP ) 63 { 64 continue; 65 } 66 67 if( IsOnline(side.pt1, line) ) 68 { 69 if( side.pt1.y > side.pt2.y ) count++; 70 } 71 else if( IsOnline(side.pt2, line) ) 72 { 73 if( side.pt2.y > side.pt1.y ) count++; 74 } 75 else if( Intersect(line, side) ) 76 { 77 count++; 78 } 79 } 80 81 if ( count % 2 == 1 ) 82 { 83 return 0; 84 } 85 else 86 { 87 return 2; 88 } 89 } 90 void gao (int xx,int yy) 91 { 92 pp.clear(); 93 Point heart; 94 heart.y = yy*2*o*0.5*sqrt(3); 95 heart.x = yy*o+xx*2*o; 96 Point p1; 97 p1.x=heart.x;p1.y=heart.y+5.0; 98 99 Point p2; 100 p2.x=heart.x+o;p2.y=heart.y+2.5; 101 102 Point p3; 103 p3.x=heart.x+o;p3.y=heart.y-2.5; 104 105 Point p4; 106 p4.x=heart.x;p4.y=heart.y-5.0; 107 108 Point p5; 109 p5.x=heart.x-o;p5.y=heart.y-2.5; 110 111 Point p6; 112 p6.x=heart.x-o;p6.y=heart.y+2.5; 113 114 pp.push_back(p1); 115 pp.push_back(p2); 116 pp.push_back(p3); 117 pp.push_back(p4); 118 pp.push_back(p5); 119 pp.push_back(p6); 120 121 } 122 int main() 123 { 124 //freopen("de.txt","r",stdin); 125 double xx,yy; 126 vector <pair <int ,int>> ans; 127 while (~scanf("%lf%lf",&xx,&yy)){ 128 Point nowpt; 129 nowpt.x=xx,nowpt.y=yy; 130 bool f=false; 131 for (int i=-9;i<=10;++i){ 132 for (int j=-9;j<=10;++j){ 133 if (!f){ 134 gao(i,j); 135 if (InPolygon(pp,nowpt)==0){ 136 ans.push_back(make_pair(i,j)); 137 f=true; 138 break; 139 } 140 } 141 142 } 143 } 144 145 } 146 int sz = ans.size(); 147 for (int i=0;i<sz;++i){ 148 printf("[%d,%d]",ans[i].first,ans[i].second); 149 if (i!=sz-1){ 150 printf(", "); 151 } 152 else{ 153 printf("\n"); 154 } 155 156 } 157 return 0; 158 }
以上是关于2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 GSM Base Station Identification (点在多边形内模板)的主要内容,如果未能解决你的问题,请参考以下文章
2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 GSM Base Station Identification (点在多边形内模板)
G.Finding the Radius for an Inserted Circle 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛
Finding the Radius for an Inserted Circle (2017 ACM-ICPC 亚洲区(南宁赛区)网络赛)