USACO Shaping Regions,難題,離散化,矩形切割,逆序染色

噁心死的題目,暴力法超時超空間。
思路:
從最上面一層(N)到第一層(0,白色層)開始分析着色的rect,使用cut函數
思路是第i層的rect和他上面的全部rect進行對比, 若是本層的rect遇到有一部分被上層的rect覆蓋,就把覆蓋掉的部分給去掉;直到最後的部分是沒有被覆蓋的,就將其記載;

php

/* 
ID: wangxin12 
PROG: rect1
LANG: C++ 
*/ 
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <cstring>
using namespace std;

struct rect {
	int x1, y1, x2, y2, color;

	rect(int lx, int ly, int rx, int ry, int c) {
		x1 = lx; y1 = ly; x2 = rx; y2 = ry; color = c; 
	}
	rect() { }
	void reset(int lx, int ly, int rx, int ry, int c) {
		x1 = lx; y1 = ly; x2 = rx; y2 = ry; color = c; 
	}
};

int A, B, N; //1 <= A,B <= 10000; N <= 1000
int colors[2501];  // color <= 2500;
rect rects[1001];

int cut(int x1, int y1, int x2, int y2, int index) {
	while(index <= N && 
		(x1 >= rects[index].x2 ||
		y1 >= rects[index].y2 ||
		x2 <= rects[index].x1 ||
		y2 <= rects[index].y1))      //和第index個着色rect沒有相交
		index++; //繼續和下一個rect進行比較

	if(x1 == x2 || y1 == y2) return 0;
	if(index > N) return (x2 - x1) * (y2 - y1);

	//有第index個rect相交,進行切割
	int ans = 0;
	if(x1 < rects[index].x1) {
		ans += cut(x1, y1, rects[index].x1, y2, index );
		x1 = rects[index].x1;
	}
	if(x2 > rects[index].x2) {
		ans += cut(rects[index].x2, y1, x2, y2, index );
		x2 = rects[index].x2;
	}
	if(y1 < rects[index].y1) {
		ans += cut(x1, y1, x2, rects[index].y1, index );
		y1 = rects[index].y1;
	}
	if(y2 > rects[index].y2) {
		ans += cut(x1, rects[index].y2, x2, y2, index );
		y2 = rects[index].y2;
	}
	return ans;

}

int main() {
	ifstream fin("rect1.in");
	ofstream fout("rect1.out");
	
	int i, j;
	fin>>A>>B>>N;
	rects[0].reset(0, 0, A, B, 1); //white paper
	for(i = 1; i <= N; i++) {
		int x1, y1, x2, y2, c;
		fin>>x1>>y1>>x2>>y2>>c;
		rects[i].reset(x1, y1, x2, y2, c);
	}

	
	memset(colors, 0, sizeof(colors));
	for(i = N; i >= 0; i--) {
		colors[rects[i].color] += cut(rects[i].x1, rects[i].y1, rects[i].x2, rects[i].y2, i + 1);
	}

	for(j = 1; j <= 2500; j++) {
		if(colors[j] > 0)
			fout<<j<<" "<<colors[j]<<endl;
	}

	fin.close();
	fout.close();

	return 0;
}

 

描述

 

N個不一樣的顏色的不透明的長方形(1 <= N <= 1000)被放置在一張橫寬爲A豎長爲B的白紙上。 這些長方形被放置時,保證了它們的邊與白紙的邊緣平行。 全部的長方形都放置在白紙內,因此咱們會看到不一樣形狀的各類顏色。 座標系統的原點(0,0)設在這張白紙的左下角,而座標軸則平行於邊緣。ios

[編輯]格式

PROGRAM NAME: rect1ide

INPUT FORMAT:函數

(file rect1.in)spa

按順序輸入放置長方形的方法。第一行輸入的是那個放在底的長方形(即白紙)。code

第 1 行: A , B 和 N, 由空格分開 (1 <=A, B<=10,000)string

第 2 到N+1行: 爲五個整數 llx, lly, urx, ury, color 這是一個長方形的左下角座標,右上角座標(x+1,y+1)和顏色。it

顏色 1和底部白紙的顏色相同。 (1 <= color <= 2500)io

OUTPUT FORMAT:class

(file rect1.out)

輸出且僅輸出全部能被看到顏色,和該顏色的總面積(能夠由若干個不連通的色塊組成),按color增序排列。

[編輯]SAMPLE INPUT

20 20 3
2 2 18 18 2
0 8 19 19 3
8 0 10 19 4

.......

[編輯]SAMPLE OUTPUT

1 91
2 84
3 187
4 38

[編輯]INPUT EXPLANATION

請注意:被(0,0)和(2,2)所描繪的是2個單位寬、2個單位高的區域

這裏有一個示意圖輸入:

11111111111111111111
33333333443333333331
33333333443333333331
33333333443333333331
33333333443333333331
33333333443333333331
33333333443333333331
33333333443333333331
33333333443333333331
33333333443333333331
33333333443333333331
33333333443333333331
11222222442222222211
11222222442222222211
11222222442222222211
11222222442222222211
11222222442222222211
11222222442222222211
11111111441111111111
11111111441111111111

'4'在(8,0)與(10,19)造成的是寬爲2的區域,而不是3.(也就是說,4造成的區域包含(8,0)和(8,1) ,而不是(8,0)和(8,2)) 。

相關文章
相關標籤/搜索