[USACO 3.1.4] rect1(漂浮法)

N(1 ≤ N ≤ 1,000)个不同颜色的不透明矩形被摆放在了一个白色的宽A高B(1 ≤ A,B ≤ 10,000)的网格上,矩形的边与网格的边平行。所有的长方形都放置在网格内,所以我们会看到不同形状的各种颜色。

坐标系统的原点(0,0)设在这张白纸的左下角,而坐标轴则平行于网格边缘。求最后能看到的颜色,以及各颜色所占面积。

输入:
第1 行包含三个整数A、B 和N,由空格分开。
第2 到N+1 行,每行五个整数:llx, lly, urx, ury, color,分别表示一个长方形的左下角坐标,右上角坐标和颜色。颜色1 和底部白纸的颜色相同(1 ≤ color ≤2,500)。矩形在输入文件中出现的顺序即为放置的先后顺序。

这道题用到的方法叫做漂浮法

想象一下,矩形倒序从水底一个一个地浮上来,如果遇到上面有东西的部分就停住,没有被挡住的地方继续上浮...

如何实现?

用一个变量记录当前浮到第几层,找到它上面第一个有交集的,分成四部分继续递归。

分成四部分的时候,每查完一个要改一下当前边界。

核心代码:

(F = Floor,C = Ceil)

int dfs(int L,int R,int F,int C,int k) {
    while(k <= n && (L >= r[k].x2 || R <= r[k].x1 || F >= r[k].y2 || C <= r[k].y1))
        k++;
    if(k > n) return (R-L)*(C-F);
    int sum = 0;
    if(L < r[k].x1) sum += dfs(L,r[k].x1,F,C,k+1), L = r[k].x1;
    if(R > r[k].x2) sum += dfs(r[k].x2,R,F,C,k+1), R = r[k].x2;
    if(F < r[k].y1) sum += dfs(L,R,F,r[k].y1,k+1), F = r[k].y1;
    if(C > r[k].y2) sum += dfs(L,R,r[k].y2,C,k+1), C = r[k].y2;
    return sum;
}

代码如下

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define MogeKo qwq
using namespace std;

const int maxn = 2505;
int a,b,n,ans[maxn];

struct rec {
    int x1,x2,y1,y2,col;
} r[maxn];


int dfs(int L,int R,int F,int C,int k) {
    while(k <= n && (L >= r[k].x2 || R <= r[k].x1 || F >= r[k].y2 || C <= r[k].y1))
        k++;
    if(k > n) return (R-L)*(C-F);
    int sum = 0;
    if(L < r[k].x1) sum += dfs(L,r[k].x1,F,C,k+1), L = r[k].x1;
    if(R > r[k].x2) sum += dfs(r[k].x2,R,F,C,k+1), R = r[k].x2;
    if(F < r[k].y1) sum += dfs(L,R,F,r[k].y1,k+1), F = r[k].y1;
    if(C > r[k].y2) sum += dfs(L,R,r[k].y2,C,k+1), C = r[k].y2;
    return sum;
}

int main() {
    scanf("%d%d%d",&a,&b,&n);
    for(int i = 1; i <= n; i++)
        scanf("%d%d%d%d%d",&r[i].x1,&r[i].y1,&r[i].x2,&r[i].y2,&r[i].col);
    ans[1] = a*b;
    for(int i = n; i >= 1; i--) {
        int s = dfs(r[i].x1,r[i].x2,r[i].y1,r[i].y2,i+1);
        ans[r[i].col] += s;
        ans[1] -= s;
    }
    for(int i = 1; i <= maxn; i++)
        if(ans[i])
            printf("%d %d
",i,ans[i]);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/mogeko/p/11808393.html