ural 1245. Pictures
1245. Pictures
Time limit: 1.0 second
Memory limit: 64 MB
Memory limit: 64 MB
Artist Ivanov (not the famous Ivanov who painted "Christ's apparition to people", but one of the many namesakes) once managed to rent inexpensively an excellent studio. Alas, as he soon discovered, the inexpensiveness was caused by objective reasons. A murder happened long ago in the house where he rented the room, and now the ghost living in the house each night renews blood spots on the walls of all the rooms. Ivanov's studio did not escape this damnation.
Nevertheless, being a creative person, Ivanov quickly found a simple solution to the problem. He decided to paint one or two pictures and hang them on the (single) wall where the spots appear each night so that the spots would be covered by the pictures. Of course, he does not want to spend too much time doing this work. That is why he plans to use not more than two pictures and wants the total area of the pictures to be minimal.
All the blood spots are circles. Each picture has a rectangular form with sides parallel to the axes, and the minimally possible size of a picture in each of the dimensions is 100 millimeters. If it is necessary to paint two pictures, then they should be hanged to the wall without overlaying. Each spot must be covered by exactly one picture.
Input
The first line contains the number of the spots N, 0 < N ≤ 1000. Each of the next N lines contains the description of the corresponding spot. A spot is described by three positive integers; they are the radius of the spot and the Cartesian coordinates of the center of the spot. Everything is measured in millimeters and all these numbers do not exceed 10000.
Output
Output the minimal total area (in square millimeters) of the pictures (not more than two) necessary to cover all the spots.
Sample
input | output |
---|---|
3 50 50 50 50 250 50 10 150 250 |
40000 |
Problem Author: Alexander Petrov (text — Leonid Volkov)
Problem Source: Ural State University Personal Programming Contest, March 1, 2003
Problem Source: Ural State University Personal Programming Contest, March 1, 2003
Tags: none
Difficulty: 898
题意:平面上有一些圆,半径ri,圆心(xi,yi),问用不超过两个矩阵覆盖他们的最小面积。注意:一个圆不能被两个矩形覆盖。
分析:显然,因为一个圆不能被两个矩形覆盖,瞬间变的简单。
矩形边界必为某个圆的上下左右的切线。
枚举即可。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cmath> 5 #include <deque> 6 #include <vector> 7 #include <queue> 8 #include <iostream> 9 #include <algorithm> 10 #include <map> 11 #include <set> 12 #include <ctime> 13 #include <iomanip> 14 using namespace std; 15 typedef long long LL; 16 typedef double DB; 17 #define For(i, s, t) for(int i = (s); i <= (t); i++) 18 #define Ford(i, s, t) for(int i = (s); i >= (t); i--) 19 #define Rep(i, t) for(int i = (0); i < (t); i++) 20 #define Repn(i, t) for(int i = ((t)-1); i >= (0); i--) 21 #define rep(i, x, t) for(int i = (x); i < (t); i++) 22 #define MIT (2147483647) 23 #define INF (1000000001) 24 #define MLL (1000000000000000001LL) 25 #define sz(x) ((int) (x).size()) 26 #define clr(x, y) memset(x, y, sizeof(x)) 27 #define puf push_front 28 #define pub push_back 29 #define pof pop_front 30 #define pob pop_back 31 #define ft first 32 #define sd second 33 #define mk make_pair 34 inline void SetIO(string Name) 35 { 36 string Input = Name+".in", 37 Output = Name+".out"; 38 freopen(Input.c_str(), "r", stdin), 39 freopen(Output.c_str(), "w", stdout); 40 } 41 42 inline int Getint() 43 { 44 int Ret = 0; 45 char Ch = ' '; 46 bool Flag = 0; 47 while(!(Ch >= '0' && Ch <= '9')) 48 { 49 if(Ch == '-') Flag ^= 1; 50 Ch = getchar(); 51 } 52 while(Ch >= '0' && Ch <= '9') 53 { 54 Ret = Ret * 10 + Ch - '0'; 55 Ch = getchar(); 56 } 57 return Flag ? -Ret : Ret; 58 } 59 60 const int N = 1010, M = 100; 61 struct Point 62 { 63 int x, y, r; 64 65 inline void Read() 66 { 67 r = Getint(); 68 x = Getint(); 69 y = Getint(); 70 } 71 72 inline bool operator <(const Point &A) const 73 { 74 return x < A.x; 75 } 76 } Arr[N]; 77 int n; 78 int LU[N], LD[N], RU[N], RD[N], Left[N], Right[N]; 79 int Ans = MIT; 80 81 inline void Input() 82 { 83 n = Getint(); 84 For(i, 1, n) Arr[i].Read(); 85 } 86 87 inline void Work() 88 { 89 sort(Arr + 1, Arr + 1 + n); 90 Right[0] = -INF, LD[0] = INF, LU[0] = -INF; 91 For(i, 1, n) 92 { 93 Right[i] = max(Right[i - 1], Arr[i].x + Arr[i].r); 94 LU[i] = max(LU[i - 1], Arr[i].y + Arr[i].r); 95 LD[i] = min(LD[i - 1], Arr[i].y - Arr[i].r); 96 } 97 Left[n + 1] = INF, RD[n + 1] = INF, RU[n + 1] = -INF; 98 Ford(i, n, 1) 99 { 100 Left[i] = min(Left[i + 1], Arr[i].x - Arr[i].r); 101 RU[i] = max(RU[i + 1], Arr[i].y + Arr[i].r); 102 RD[i] = min(RD[i + 1], Arr[i].y - Arr[i].r); 103 } 104 105 For(i, 2, n) 106 if(Right[i - 1] <= Left[i]) 107 Ans = min(Ans, 108 max(M, Right[i - 1] - Left[1]) * max(M, LU[i - 1] - LD[i - 1]) + 109 max(M, Right[n] - Left[i]) * max(M, RU[i] - RD[i])); 110 } 111 112 inline void Solve() 113 { 114 Work(); 115 For(i, 1, n) swap(Arr[i].x, Arr[i].y); 116 Work(); 117 118 Ans = min(Ans, max(M, Right[n] - Left[1]) * max(M, LU[n] - LD[n])); 119 120 printf("%d\n", Ans); 121 } 122 123 int main() 124 { 125 #ifndef ONLINE_JUDGE 126 SetIO("D"); 127 #endif 128 Input(); 129 Solve(); 130 return 0; 131 }