1. 程式人生 > >2017 ACM-ICPC 亞洲區(南寧賽區)網絡賽 GSM Base Station Identification (點在多邊形內模板)

2017 ACM-ICPC 亞洲區(南寧賽區)網絡賽 GSM Base Station Identification (點在多邊形內模板)

ace fab amp ems mea type 頂點 == present

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 (點在多邊形內模板)