usaco Shaping Regions

有太多不知道,又常常焦急地想去知道,因为这份心情,所以我愿意将我会的与大家分享

——这也是我创建这个博客的目的!

今天发现自己辛辛苦苦做出一个题目后,越来越懒得写说明了。

突然想起了自己当初创建这个博客时,是抱着份什么心情............

hehe!

这道真的很有意思!做了两天!今天终于做出来了,真的很高兴。。。。

INPUT FORMAT

The order of the input lines dictates the order of laying down the rectangles. The first input line is a rectangle "on the bottom".

Line 1:A, B, and N, space separated (1 <= A,B <= 10,000)
Lines 2-N+1:Five integers: llx, lly, urx, ury, color: the lower left coordinates and upper right coordinates of the rectangle whose color is `color' (1 <= color <= 2500) to be placed on the white sheet. The color 1 is the same color of white as the sheet upon which the rectangles are placed.

其实题目看起来不难,如果数据小点,开个二维数组, 直接模拟也是可以出答案的。
但这个想法是好的,出题者是无情的。
测试数据A、B都达到了10000,开个10000*10000的二维数组。肯定不成!
这也是这道题目的难点。如何实现数据压缩。
题目过程就像在纸上画各色的矩形一样
(矩形的边都平行于纸的轮廓,假设颜色不叠加,并且完全覆盖), 
最后纸上图案会变成什么样呢?
有一点可以想像的的出——就是图案可以拆分出若干个矩形,每个矩形内着色完全相同。
好下图所示
  
我选择存储矩形
struct rectangle {
int x1, y1;
int x2, y2;
}rec[100000];
rec数组初始化存入(0, 0), (A, B);然后就是模拟过程;
我的方法是判断新画到纸上的矩阵有没有切割数组中的矩阵rec[i],
分为2种情况:
1、当前画的矩阵完全包含rec[i],表示新画的矩形完全覆盖rec[i],当删除rec[i].
2、当前画的矩阵的4条边分别是否与rec[i]相交,若相交则会将rec[i]分成两个矩形。
然后将当前画的矩阵加入到rec数组中。
细节自己体会了!!!hehe....
代码如下:
/*  
ID: guo geer  
PROG: rect1
LANG: C++  
*/

#include<iostream>
#include<fstream>
using namespace std;

struct rectangle {
	int x1, y1;
	int x2, y2;
};
int c[100000];
rectangle rec[100000];

int line(int a, int b, int x, int y) // a < b, x < y,  [a, b]&[x, y] != NULL
{
	if(x > a && x < b)
		return 1;
	if(y > a && y < b)
		return 1;
	if(x <= a && y >= b)
		return 1;
	return 0;
}

int main()
{
	ifstream fin("rect1.in");
	ofstream fout("rect1.out");

	int a, b, n;
	int i,j,k;
	while(fin>>a>>b>>n)
	{
		int count = 0;
		rec[0].x1 = 0, rec[0].y1 = 0;
		rec[0].x2 = a, rec[0].y2 = b;
		c[0] = 1;
		count ++;

		int x1, y1, x2, y2, col;
		for(k=0; k<n; k++)
		{
			fin>>x1>>y1>>x2>>y2>>col;
			for(i=0; i<count; i++)
			{
			if(rec[i].x1 >= x1 && rec[i].x2 <= x2 && rec[i].y1 >= y1 && rec[i].y2 <= y2)
			{
				c[i] = 0;
			}
			else if(rec[i].y1 < y1 && rec[i].y2 > y1 && line(rec[i].x1, rec[i].x2, x1, x2))
			{				
				rec[count].x1 = rec[i].x1;
				rec[count].y1 = y1;
				rec[count].y2 = rec[i].y2;
				rec[count].x2 = rec[i].x2;

				c[count] = c[i];
				count ++;

				rec[i].y2 = y1;	
			}
			else if(rec[i].x1 < x2 && rec[i].x2 > x2 && line(rec[i].y1, rec[i].y2, y1, y2))
			{	

				rec[count].x2 = x2;
				rec[count].y2 = rec[i].y2;
				rec[count].y1 = rec[i].y1;
				rec[count].x1 = rec[i].x1;

				c[count] = c[i];
				count ++;

				rec[i].x1 = x2;	
			}
			else if(rec[i].y1 < y2 && rec[i].y2 > y2 && line(rec[i].x1, rec[i].x2, x1, x2))
			{
				
				rec[count].x1 = rec[i].x1;
				rec[count].y1 = rec[i].y1;
				rec[count].y2 = y2;
				rec[count].x2 = rec[i].x2;

				c[count] = c[i];
				count ++;

				rec[i].y1 = y2;	
			}
			else if(rec[i].x1 < x1 && rec[i].x2 > x1 && line(rec[i].y1, rec[i].y2, y1, y2))
			{				
				rec[count].x1 = x1;
				rec[count].y1 = rec[i].y1;
				rec[count].y2 = rec[i].y2;
				rec[count].x2 = rec[i].x2;

				c[count] = c[i];
				count ++;

				rec[i].x2 = x1;	
			}
			}
			int count_1 = 0;
			for(j=0; j<count; j++)
				if(c[j] != 0)
				{
					rec[count_1] = rec[j];
					c[count_1] = c[j];
					count_1 ++;
				}
	
			count = count_1;
			rec[count].x1 = x1;
			rec[count].y1 = y1;
			rec[count].x2 = x2;
			rec[count].y2 = y2;
			c[count] = col;
			count ++;
		}
	
		int res[2501];
		for(i=0; i<= 2500; i++)
			res[i] = 0;

		for(i=0; i<count; i++)
			res[c[i]] += (rec[i].y2 - rec[i].y1) * (rec[i].x2 - rec[i].x1);

		for(i=1; i<= 2500; i++)
			if(res[i] != 0)
				fout<<i<<' '<<res[i]<<endl;
	}
	return 0;
}





 

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值