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?
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 }