bzoj 1020[SHOI2008]安全的航線flight - 叠代+二分
阿新 • • 發佈:2018-02-10
out 就是 ron 輸出 input mage 起點 一個 con
-9 -6
5 1
3
0 16
-16 -12
17 -6
1020: [SHOI2008]安全的航線flight
Time Limit: 5 Sec Memory Limit: 162 MBDescription
在設計航線的時候,安全是一個很重要的問題。首先,最重要的是應采取一切措施確保飛行不會發生任何事故
,但同時也需要做好最壞的打算,一旦事故發生,就要確保乘客有盡量高的生還幾率。當飛機迫降到海上的時候,
最近的陸地就是一個關鍵的因素。航線中最危險的地方就是距離最近的陸地最遠的地方,我們稱這種點為這條航線
“孤地點”。孤地點到最近陸地的距離被稱為“孤地距離”。作為航空公司的高級顧問,你接受的第一個任務就是
盡量找出一條航線的孤地點,並計算這條航線的孤地距離。為了簡化問題,我們認為地圖是一個二維平面,陸地可
以用多邊形近似,飛行線路為一條折線。航線的起點和終點都在陸地上,但中間的轉折點是可能在海上(如下圖所
示,方格標示出了孤地點)。
Input
輸入的第一行包括兩個整數C和N(1≤C≤20,2≤N≤20),分別代表陸地的數目的航線的轉折點的數目。接下
來有N行,每行有兩個整數x,y。(x,y)表示一個航線轉折點的坐標,第一個轉折點為航線的起點,最後一個轉折點
為航線的終點。接下來的輸入將用來描述C塊大陸。每塊輸入由一個正整數M開始(M≤30),M表示多邊形的頂點個
數,接下來的M行,每行會包含兩個整數x,y,(x,y)表示多邊形的一個頂點坐標,我們保證這些頂點以順時針或逆
時針給出了該多邊形的閉包,不會出現某些邊相交的情況。此外我們也保證輸入數據中任何兩塊大陸不會相交。輸
入的所有坐標將保證在-10000到10000的範圍之間。
Output
輸出一個浮點數,表示航線的孤地距離,數據保留2位小數。
Sample Input
1 2-9 -6
5 1
3
0 16
-16 -12
17 -6
Sample Output
0.00 是一道叠代思想的應用 詳情—— 莫濤《叠代思想的應用》 具體的思路就是我們先將初始的所有飛行線路的線段都放入一個隊列中 然後先求出線段兩端點到大陸的最近點,然後二分找到線段上到兩點距離相同的點, 記為d 如果d < ans, 我們就沒有必要再考慮這條線段。 因為一個線段上的點到大陸的最短距離必然 <d 可以想象距離為d的點向左右移動距離變小 之後我們將線段從中間分為兩段放入隊列 直到隊列為空 代碼惡心的要死1 #include <iostream> 2 #include <queue> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #include <cstdio> 7 #define LL long long 8 9 using namespace std; 10 11 int C, N; 12 double ans = 0; 13 14 double eps = 1e-14; 15 inline LL read() 16 { 17 LL x = 0, w = 1; char ch = 0; 18 while(ch < ‘0‘ || ch > ‘9‘) { 19 if(ch == ‘-‘) { 20 w = -1; 21 } 22 ch = getchar(); 23 } 24 while(ch >= ‘0‘ && ch <= ‘9‘) { 25 x = x * 10 + ch - ‘0‘; 26 ch = getchar(); 27 } 28 return x * w; 29 } 30 31 struct vec { 32 double x, y; 33 }; 34 35 struct NODE { 36 double x, y; 37 } p1, p2, tt, mid, l, r, p; 38 39 struct node { 40 double x[30], y[30]; 41 int M; 42 } n, land[40]; 43 44 struct edge { 45 double x1, y1; 46 double x2, y2; 47 } la[100], fl[100], temp, t; 48 49 double disnode(NODE a, NODE b) 50 { 51 return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); 52 } 53 54 double dis(double x1, double y1, double x2, double y2) 55 { 56 return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); 57 } 58 59 NODE operator +(NODE a, NODE b) 60 { 61 NODE temp; 62 temp.x = a.x + b.x; 63 temp.y = a.y + b.y; 64 return temp; 65 } 66 67 NODE operator /(NODE a, double k) 68 { 69 NODE temp; 70 temp.x = a.x / k; 71 temp.y = a.y / k; 72 return temp; 73 } 74 bool in(double x, double y, int k) 75 { 76 int cnt = 0; 77 for(int i = 0; i < land[k].M; i++) { 78 double x1 = land[k].x[i], y1 = land[k].y[i]; 79 double x2 = land[k].x[(i + 1) % land[k].M], y2 = land[k].y[(i + 1) % land[k].M]; 80 if((x1 == x && y1 == y) || (x2 == x && y2 == y)) { 81 return true; 82 } 83 if((y1 < y && y2 >= y) || (y1 >= y && y2 < y)) { 84 double xx = x1 + (y - y1) * (x2 - x1) / (y2 - y1); 85 if(xx == x) { 86 return true; 87 } 88 if(xx > x) { 89 cnt++; 90 } 91 } 92 } 93 return cnt % 2; 94 } 95 96 97 NODE PointToSegDist(double x, double y, double x1, double y1, double x2, double y2) 98 { 99 double cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1); 100 if (cross <= 0) { 101 tt.x = x1, tt.y = y1; 102 return tt; 103 } 104 double d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1); 105 if (cross >= d2) { 106 tt.x = x2, tt.y = y2; 107 return tt; 108 } 109 double r = cross / d2; 110 double px = x1 + (x2 - x1) * r; 111 double py = y1 + (y2 - y1) * r; 112 tt.x = px, tt.y = py; 113 return tt; 114 } 115 NODE cal(double x, double y) 116 { 117 double dmin = 1e9; 118 for(int i = 1; i <= C; i++) { 119 if(in(x, y, i)) { 120 tt.x = x, tt.y = y; 121 return tt; 122 } 123 } 124 for(int i = 1; i <= C; i++) { 125 for(int j = 0; j < land[i].M; j++) { 126 tt = PointToSegDist(x, y, land[i].x[j], land[i].y[j], land[i].x[(j + 1) % land[i].M], land[i].y[(j + 1) % land[i].M]); 127 if(dmin > dis(x, y, tt.x, tt.y)) { 128 dmin = dis(x, y, tt.x, tt.y); 129 p.x = tt.x, p.y = tt.y; 130 } 131 } 132 } 133 ans = max(ans, dis(x, y, p.x, p.y)); 134 135 return p; 136 } 137 138 queue<edge> q; 139 int sum = 0; 140 int main() 141 { 142 C = read(), N = read(); 143 for(int i = 0; i < N; i++) { 144 scanf("%lf%lf", &n.x[i], &n.y[i]); 145 } 146 for(int j = 0; j < N; j++) { 147 temp.x1 = n.x[j], temp.y1 = n.y[j]; 148 temp.x2 = n.x[(j + 1) % N], temp.y2 = n.y[(j + 1) % N]; 149 q.push(temp); 150 } 151 for(int i = 1; i <= C; i++) { 152 land[i].M = read(); 153 for(int j = 0; j < land[i].M; j++) { 154 scanf("%lf%lf", &land[i].x[j], &land[i].y[j]); 155 } 156 } 157 while(!q.empty()) { 158 temp = q.front(); 159 //cout<<temp.x1<<" "<<temp.y1<<" "<<temp.x2<<" "<<temp.y2<<endl; 160 q.pop(); 161 double x1 = temp.x1, x2 = temp.x2, y1 = temp.y1, y2 = temp.y2; 162 p1 = cal(x1, y1), p2 = cal(x2, y2); 163 l.x = x1, l.y = y1, r.x = x2, r.y = y2; 164 while(disnode(r, l) >= eps) { 165 // cout<<l.x<<" "<<l.y<<" "<<endl<<r.x<<" "<<r.y<<" "<<endl<<disnode(l, r)<<endl<<endl; 166 mid = (l + r) / 2; 167 if (disnode(mid, p1) < disnode(mid, p2)) { 168 l = mid; 169 } else { 170 r = mid; 171 } 172 } 173 cal(mid.x, mid.y); 174 if(min(disnode(l, p1), disnode(r, p2)) > ans + 0.005) { 175 t = temp; 176 t.x2 = mid.x, t.y2 = mid.y; 177 q.push(t); 178 t = temp; 179 t.x1 = mid.x, t.y1 = mid.y; 180 q.push(t); 181 } 182 } 183 printf("%.2lf", ans); 184 return 0; 185 } 186 187 188 /* 189 1 2 190 191 -9 -6 192 193 5 1 194 195 3 196 197 0 16 198 199 -16 -12 200 201 17 -6 202 203 */View Code
bzoj 1020[SHOI2008]安全的航線flight - 叠代+二分