平面内有n个矩形, 第i个矩形的左下角坐标为(x1[i], y1[i]), 右上角坐标为(x2[i], y2[i])。
如果两个或者多个矩形有公共区域则认为它们是相互重叠的(不考虑边界和角落)。
请你计算出平面内重叠矩形数量最多的地方,有多少个矩形相互重叠。
平面内有n个矩形, 第i个矩形的左下角坐标为(x1[i], y1[i]), 右上角坐标为(x2[i], y2[i])。
如果两个或者多个矩形有公共区域则认为它们是相互重叠的(不考虑边界和角落)。
请你计算出平面内重叠矩形数量最多的地方,有多少个矩形相互重叠。
输入包括五行。
第一行包括一个整数n(2 <= n <= 50), 表示矩形的个数。
第二行包括n个整数x1[i](-10^9 <= x1[i] <= 10^9),表示左下角的横坐标。
第三行包括n个整数y1[i](-10^9 <= y1[i] <= 10^9),表示左下角的纵坐标。
第四行包括n个整数x2[i](-10^9 <= x2[i] <= 10^9),表示右上角的横坐标。
第五行包括n个整数y2[i](-10^9 <= y2[i] <= 10^9),表示右上角的纵坐标。
输出一个正整数, 表示最多的地方有多少个矩形相互重叠,如果矩形都不互相重叠,输出1。
2 0 90 0 90 100 200 100 200
2
n = int(input()) x1 = [int(i) for i in input().split()] y1 = [int(i) for i in input().split()] x2 = [int(i) for i in input().split()] y2 = [int(i) for i in input().split()] result = 0; for x in x1+x2: for y in y1+y2: count = 0 for i in range(n): if x >= x1[i] and y >= y1[i] and x < x2[i] and y < y2[i]: count += 1 result = max(result, count) print(result)
方法一
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
public class Main {
private static int n;
private static int[][] rec; //0下标记录重叠计数
private static List newRec;
private static long res = 1;
public static void main(String[] args){
int loop = 1;
//System.setIn(No2.class.getResourceAsStream("2.txt"));
Scanner scanner = new Scanner(System.in);
//loop = scanner.nextInt();
for (int i = 0; i < loop; ++i) {
n = scanner.nextInt();
rec = new int[n][5];
newRec = new ArrayList();
for (int j = 1; j <= 4; j++) {
for (int k = 0; k < n; k++) {
rec[k][j] = scanner.nextInt();
}
}
for (int k = 0; k < n; k++) {
rec[k][0] = 1;
}
solve();
output();
}
scanner.close();
}
private static void solve() {
for (int i = 1; i < n; i++) {
int[] cover;
for (int j = 0, len = newRec.size(); j < len; ++j) {
if((cover = getCover(newRec.get(j), rec[i])) != null) {
newRec.add(cover);
}
}
for (int j = 0; j < i; j++) {
if((cover = getCover(rec[j], rec[i])) != null)
newRec.add(cover);
}
}
}
private static int[] getCover(int[] a, int[] b) {
int x1 = Math.max(a[1], b[1]);
int y1 = Math.max(a[2], b[2]);
int x2 = Math.min(a[3], b[3]);
int y2 = Math.min(a[4], b[4]);
if(x1 < x2 && y1 < y2) {
res = Math.max(res, a[0] + b[0]);
return new int[]{a[0] + b[0], x1, y1, x2, y2};
}
return null;
}
private static void output() {
System.out.println(res);
}
}
方法二
点计数法,重叠后的矩形左下角坐标一定是{x1[0]~x1[50], y1[0]~y1[50]}这2500个点中产生,只要分别判断这些点在多少矩形中即可
import java.util.Scanner;
public class Main {
private static int n;
private static int[][] rec;
private static long res = 1;
public static void main(String[] args){
int loop = 1;
//System.setIn(No2.class.getResourceAsStream("2.txt"));
Scanner scanner = new Scanner(System.in);
//loop = scanner.nextInt();
for (int i = 0; i < loop; ++i) {
n = scanner.nextInt();
rec = new int[n][4];
for (int j = 0; j < 4; j++) {
for (int k = 0; k < n; k++) {
rec[k][j] = scanner.nextInt();
}
}
solve();
output();
}
scanner.close();
}
private static void solve() {
int x, y, count;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
x = Math.max(rec[i][0], rec[j][0]);
y = Math.max(rec[i][1], rec[j][1]);
count = 0;
for (int k = 0; k < n; k++) {
if(x >= rec[k][0] && y >= rec[k][1] && x < rec[k][2] && y < rec[k][3])
++count;
}
res = Math.max(count, res);
}
}
}
private static void output() {
System.out.println(res);
}
}
左程云的思路:最大重叠区域的底边一定是某个矩形的底边。 方法: 1 按下边界对矩形升序排序 2 遍历每个矩形,构造这样一个集合:集合中其他矩形的下边界小于等于该矩形的下边界, 集合中其他矩形的上边界大于该矩形的下边界 3 对每个集合调用最大线段重叠问题算法原型 import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.Arrays; import java.util.PriorityQueue; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int[] x1 = new int[n]; int[] y1 = new int[n]; int[] x2 = new int[n]; int[] y2 = new int[n]; for (int i = 0; i < n; i++) { x1[i] = scanner.nextInt(); } for (int i = 0; i < n; i++) { y1[i] = scanner.nextInt(); } for (int i = 0; i < n; i++) { x2[i] = scanner.nextInt(); } for (int i = 0; i < n; i++) { y2[i] = scanner.nextInt(); } Node[] nodes = new Node[x1.length]; for (int i = 0; i < nodes.length; i++) { nodes[i] = new Node(x1[i], y1[i], x2[i], y2[i]); } System.out.println(maxRectangleCover(nodes)); } public static class Node { public int x1; public int y1; public int x2; public int y2; public Node(int x1, int y1, int x2, int y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; } } public static int maxRectangleCover(Node[] nodes) { Arrays.sort(nodes, (a, b) -> a.y1 - b.y1); PriorityQueue<Node> pq = new PriorityQueue<>((a, b) -> a.y2 - b.y2); int maxCover = 0; for (int i = 0; i < nodes.length; i++) { while (!pq.isEmpty() && pq.peek().y2 <= nodes[i].y1) { pq.poll(); } pq.add(nodes[i]); Node[] subNodes = pq.toArray(pq.toArray(new Node[0])); maxCover = Math.max(maxCover, maxLineCover(subNodes)); } return maxCover; } public static int maxLineCover(Node[] nodes) { Arrays.sort(nodes, (a, b) -> a.x1 - b.x1); PriorityQueue<Node> pq = new PriorityQueue<>((a, b) -> a.x2 - b.x2); int maxCover = 0; for (int i = 0; i < nodes.length; i++) { while (!pq.isEmpty() && pq.peek().x2 <= nodes[i].x1) { pq.poll(); } pq.add(nodes[i]); maxCover = Math.max(maxCover, pq.size()); } return maxCover; } }
#include <bits/stdc++.h> using namespace std; struct node { int point[4]; //x1,y1,x2,y2 } rec[55]; vector<int> xx; vector<int> yy; int maxn = 0; int main() { int n; cin >> n; for (int i = 0; i < 4; i++) { for (int j = 0; j < n; j++) { cin >> rec[j].point[i]; if (i % 2 == 0) xx.push_back(rec[j].point[i]); else yy.push_back(rec[j].point[i]); } } int sz = xx.size(); for (int i = 0; i < sz; i++) { for (int j = 0; j < sz; j++) { int cnt = 0; for (int t = 0; t < n; t++) { //走所有矩形 int x1 = rec[t].point[0]; int x2 = rec[t].point[2]; int y1 = rec[t].point[1]; int y2 = rec[t].point[3]; //不取等号防止重复,控制边界 if (xx[i] < x2 && xx[i] >= x1 && yy[j] < y2 && yy[j] >= y1) cnt++; } maxn = maxn > cnt ? maxn : cnt; } } cout << maxn; return 0; }
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[][] arr = new int[n][4]; List<Integer> xList = new ArrayList<>(); List<Integer> yList = new ArrayList<>(); for (int i = 0; i < 4; i++) { for (int j = 0; j < n; j++) { arr[j][i] = sc.nextInt(); if (i == 0 || i == 2) { xList.add(arr[j][i]); } if (i == 1 || i == 3) { yList.add(arr[j][i]); } } } int ret = 0; for (int x : xList) { for (int y : yList) { int cnt = 0; for (int i = 0; i < n; i++) { if (x >= arr[i][0] && x < arr[i][2] && y >= arr[i][1] && y < arr[i][3]) { cnt++; } } if (cnt > ret) { ret = cnt; } } } System.out.println(ret); } }