Distant Galaxy
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 111 Accepted Submission(s): 53
Problem Description
You
are observing a distant galaxy using a telescope above the Astronomy
Tower, and you think that a rectangle drawn in that galaxy whose edges
are parallel to coordinate axes and contain maximum star systems on its
edges has a great deal to do with the mysteries of universe. However you
do not have the laptop with you, thus you have written the coordinates
of all star systems down on a piece of paper and decide to work out the
result later. Can you finish this task?
![](http://acm.hdu.edu.cn/data/images/con229-1004-1.JPG)
Input
There
are multiple test cases in the input file. Each test case starts with
one integer N , (1<=N<=100) , the number of star systems on the
telescope. N lines follow, each line consists of two integers: the X
and Y coordinates of the K -th planet system. The absolute value of any
coordinate is no more than 109 , and you can assume that the planets
are arbitrarily distributed in the universe.
N = 0 indicates the end of input file and should not be processed by your program.
N = 0 indicates the end of input file and should not be processed by your program.
Output
For each test case, output the maximum value you have found on a single line in the format as indicated in the sample output.
Sample Input
10
2 3
9 2
7 4
3 4
5 7
1 5
10 4
10 6
11 4
4 6
0
Sample Output
Case 1: 7
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 struct T 7 { 8 int x; 9 int y; 10 bool operator <(const T& rhs) const{ 11 return x<rhs.x; 12 } 13 }poin[105]; 14 // 具体可见大白书,51页 15 //y[]表示存储所有的y的值,on[]表示左边界,on2表示右边界 16 int y[105],lef[105],on[105],on2[105]; 17 int t, m; 18 int solve() 19 { 20 sort(poin,poin+t); 21 sort(y,y+t); 22 m = unique(y,y+t) - y;//去除相同的元素,m表示去除相同的元素后,还有几个 23 if(m<=2) return t; //如果只有两种y值表示所有点都在这两条线上,直接返回 24 int ans = 0; 25 for(int a = 0; a<m; a++)//枚举所有可能的上边界和下边界 26 for(int b = a+1; b<m; b++) 27 { 28 int ymin =y[a];int ymax = y[b]; 29 int k = 0; 30 for(int i = 0; i<t;i++) 31 { 32 if(i==0 || poin[i].x!=poin[i-1].x) //判断前后的x值是否有相同的点 33 { 34 k++; 35 on[k] = on2[k] = 0; 36 lef[k] = k==0 ? 0 : lef[k-1]+ on2[k-1] - on[k-1];//此时的lef不包括右边界在它上面的点 37 } 38 if(poin[i].y>ymin && poin[i].y<ymax) on[k]++; 39 if(poin[i].y>=ymin && poin[i].y<=ymax) on2[k]++;//on2 - on 表示在线上的点 40 } 41 if(k<=2) return t;//这个地方表示少于两种的x值,只好返回本身了 42 int m =0 ; 43 for(int j =1 ;j<=k; j++) 44 { 45 ans = max(ans,lef[j]+on2[j]+m);// 大白书51页有详细介绍 46 m = max(m,on[j] - lef[j]); // 47 } 48 } 49 return ans; 50 } 51 int main() 52 { 53 int num = 1; 54 while(scanf("%d",&t) && t) 55 { 56 for(int i =0 ;i<t; i++) 57 { 58 scanf("%d %d",&poin[i].x,&poin[i].y); 59 y[i] = poin[i].y; 60 } 61 printf("Case %d: %d ",num,solve()); 62 num++; 63 } 64 return 0; 65 }