平面内有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);
}
}