UVALive 3695 Distant Galaxy 用矩阵的边覆盖二维平面上最多的点 科学的枚举

题目链接: 点击打开链接

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 , (1N100) , 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.

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

题意:

给定二维平面上的n个点,用一个矩阵去覆盖,使得尽可能多的点坐落在矩阵的边框上(坐落在内部无效)

思路:

首先枚举2条x轴,然后给y轴排序并去重,

因为y轴的枚举是有序的,所以维护一个最大值就好。

用siz表示从之前的某条y轴到当前枚举的y轴(不包括当前枚举的y轴上的点)内最多能包含多少个点

对于此时矩阵内的点数 ans = siz + 当前y轴上的所有点

维护siz:

siz = max(siz+当前y轴上的点且&& 在x轴上的点, 当前y轴上的所有点) 

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.TreeSet;
import java.util.Queue;

public class Main {
	class Node implements Comparable{
		int x, y;
		Node(){}
		Node(int x, int y){
			this.x = x; this.y = y;
		}
		public int compareTo(Node o) {
			return Integer.compare(o.y, y);
		}		
		void put(){out.println(x+" "+y);}
	}
	static int N = 110;
	int n;
	Node[] a = new Node[N];
	int[] x = new int[N], y = new int[N];
	int solve(int l, int r){
		int ans = 0, siz = 0;
		for(int i = 1; i <= n; i++)
		{
			if(i>1 && y[i]==y[i-1])continue;
			int cnt = 0, edge = 0;
			for(int j = 1; j <= n; j++)
			{
				if(y[i] == a[j].y && l <= a[j].x && a[j].x <= r){
					if(a[j].x == l || a[j].x == r)edge++;
					else cnt++;
				}
			}
			ans = max(ans, siz + cnt + edge);
			siz = max(siz, cnt);
			siz += edge;//技巧在这里
		}
		return ans;
	}
	void work() {
		int Cas = 1;
		while (true) {
			n = cin.nextInt();	if(n == 0)break;
			for(int i = 1; i <= n; i++){
				a[i] = new Node(cin.nextInt(), cin.nextInt());
				x[i] = a[i].x;
				y[i] = a[i].y;
			}
			Arrays.sort(x, 1, n+1);
			Arrays.sort(y, 1, n+1);
			int ans = 1;
			for(int i = 1; i <= n; i++)
				for(int j = i+1; j <= n; j++)
				{
					ans = max(ans, solve(x[i], x[j]));
				}
			out.println("Case "+(Cas++)+": "+ans);
		}
	}

	Main() {
		cin = new Scanner(System.in);
		out = new PrintWriter(System.out);
	}

	public static void main(String[] args) {
		Main e = new Main();
		e.work();
		out.close();
	}

	public Scanner cin;
	public static PrintWriter out;
	int max(int x, int y) {
		return x > y ? x : y;
	}
}


你可能感兴趣的:(特别的AC技巧)