1. 程式人生 > >uva 1382 Distant Galaxy

uva 1382 Distant Galaxy

復雜度 algorithm sin cmp while 進行 矩形 復雜 eof

https://vjudge.net/problem/UVA-1382

題意:

給出平面上的n個點,找出一個矩形,使得邊界上包含盡量多的點。

思路:

參考訓練指南。

首先如果枚舉起起點,終點,再進行統計的話,復雜度顯然太大了,因為坐標的範圍是10的9次方級別的。

所以,又想到掃描線的方法。

我們首先對數組排個序,枚舉上下邊界,之後,用三個數組,left[i]表示i這條線左邊(不包括這條線)的在上下邊界的點的數量,on[i]表示在i這條線上的位於上下邊界之間的點的數量(不包括上下邊界),on2[i]表示,

在i這條線上的位於上下邊界之間的點的數量(包括上下邊界),我們從左往右掃一遍,維護這三個數組的信息。

left[i] = left[i-1] + on2[i] - on[i-1],在i-1這條邊的左邊的在上下邊界上的點的數量等於它上一條邊的左邊的在上下邊界上的點的數量加上上一條邊的在上下邊界上的點的數量,on2[i-1] - on[i-1]就是位於上下邊界的點的數量。

ans = max(left[i] + on2[i]+on[k] - left[k])(k < i),我們要維護的就是on[k] - left[k]的最大值,在從左往右掃的時候維護。

一些細節的處理需要註意,比如點都在一條邊或者兩條邊上。

代碼:

 1 #include <stdio.h>
 2
#include <string.h> 3 #include <algorithm> 4 using namespace std; 5 6 struct node 7 { 8 int x,y; 9 } a[105]; 10 11 int n,m; 12 13 int y[105]; 14 int left[105],on[105],on2[105]; 15 16 bool cmp(node aa,node bb) 17 { 18 return aa.x < bb.x; 19 } 20 21 int solve(void
) 22 { 23 sort(a,a+n,cmp); 24 25 int ans = 0; 26 27 sort(y,y+n); 28 29 m = unique(y,y+n) - y; 30 31 if (m <= 2) return n; 32 33 for (int i = 0;i < m;i++) 34 for (int j = i + 1;j < m;j++) 35 { 36 int ymin = y[i],ymax = y[j]; 37 38 int num = 0; 39 40 for (int k = 0;k < n;k++) 41 { 42 if (k == 0 || a[k].x != a[k-1].x) 43 { 44 num++; 45 46 on[num] = on2[num] = 0; 47 48 left[num] = num == 0 ? 0 : left[num-1] + on2[num-1] - on[num-1]; 49 } 50 51 52 if (a[k].y > ymin && a[k].y < ymax) on[num]++; 53 if (a[k].y >= ymin && a[k].y <= ymax) on2[num]++; 54 } 55 56 if (num <= 2) return n; 57 58 int M = 0; 59 60 for (int k = 1;k <= num;k++) 61 { 62 ans = max(ans,M + left[k] + on2[k]); 63 M = max(M,on[k] - left[k]); 64 } 65 } 66 67 return ans; 68 } 69 70 int main() 71 { 72 int kase = 0; 73 74 while (scanf("%d",&n) != EOF) 75 { 76 if (!n) break; 77 78 for (int i = 0;i < n;i++) 79 { 80 scanf("%d%d",&a[i].x,&a[i].y); 81 82 y[i] = a[i].y; 83 } 84 85 int ans = solve(); 86 87 printf("Case %d: %d\n",++kase,ans); 88 } 89 90 return 0; 91 }

uva 1382 Distant Galaxy