51nod - 1562 玻璃切割

现在有一块玻璃,是长方形的(w 毫米× h 毫米),现在要对他进行切割。

切割的方向有两种,横向和纵向。每一次切割之后就会有若干块玻璃被分成两块更小的玻璃。在切割之后玻璃不会被移动。

现在想知道每次切割之后面积最大的一块玻璃是多少。

样例解释:

 

对于第四次切割,下面四块玻璃的面积是一样大的。都是2。

 

Input

单组测试数据。
第一行有三个整数 w,h,n (2≤w,h≤200000, 1≤n≤200000),表示玻璃在横向上长w 毫米,纵向上长h 毫米,接下来有n次的切割。
接下来有n行输入,每一行描述一次切割。
输入的格式是H y 或 V x。
H y表示横向切割,切割线距离下边缘y毫米(1≤y≤h-1)。
V x表示纵向切割,切割线距离左边缘x毫米(1≤x≤w-1)。
输入保证不会有两次切割是一样的。

Output

对于每一次切割,输出所有玻璃中面积最大的是多少。

Input示例

样例输入1
4 3 4
H 2
V 2
V 3
V 1

Output示例

样例输出1
8
4
4
2

思路:

并查集。可以先简化问题,比如只在水平方向进行切割,将高度每隔1个单位初始化rank为1,如果该点未被切割,则向下一个点进行合并,计算新的最大高度。最后将做法扩展到垂直方向即可。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
 
typedef long long int ll;
const int MAXN = 2e5 + 10;
int w, h, n;
int input[MAXN];
bool isVer[MAXN];
bool visW[MAXN];
bool visH[MAXN];
int parentW[MAXN];
int parentH[MAXN];
int rankW[MAXN];
int rankH[MAXN];
int maxW;
int maxH;
ll result[MAXN];
char dir;
 
int findH(int x)
{
	if (x != parentH[x])
	{
		parentH[x] = findH(parentH[x]);
	}
 
	return parentH[x];
}
 
void joinH(int x, int y)
{
	x = findH(x);
	y = findH(y);
 
	if (x == y)
	{
		return;
	}
 
	parentH[x] = y;
	rankH[y] += rankH[x];
 
	maxH = max(maxH, rankH[y]);
}
 
int findW(int x)
{
	if (x != parentW[x])
	{
		parentW[x] = findW(parentW[x]);
	}
 
	return parentW[x];
}
 
void joinW(int x, int y)
{
	x = findW(x);
	y = findW(y);
 
	if (x == y)
	{
		return;
	}
 
	parentW[x] = y;
	rankW[y] += rankW[x];
 
	maxW = max(maxW, rankW[y]);
}
 
void init()
{
	for (int i = 1; i <= w; i++)
	{
		parentW[i] = i;
		rankW[i] = 1;
	}
 
	for (int i = 1; i <= h; i++)
	{
		parentH[i] = i;
		rankH[i] = 1;
	}
	maxW = 1;
	maxH = 1;
 
	rankW[0] = 0;
	rankH[0] = 0;
 
	memset(visW, false, sizeof(visW));
	memset(visH, false, sizeof(visH));
}
 
int main()
{
	cin >> w >> h >> n;
	init();
 
	for (int i = 0; i < n; i++)
	{
		cin >> dir >> input[i];
		if (dir == 'H')
		{
			isVer[i] = false;
			visH[input[i]] = true;
		}
		else
		{
			isVer[i] = true;
			visW[input[i]] = true;
		}
	}
 
	for (int i = 1; i < w; i++)
	{
		if (!visW[i])
		{
			joinW(i, i + 1);
		}
	}
 
	for (int i = 1; i < h; i++)
	{
		if (!visH[i])
		{
			joinH(i, i + 1);
		}
	}
 
	for (int i = n - 1;  i >= 0; i--)
	{
		result[i] = (ll)(maxH) * maxW;
 
		if (isVer[i])
		{
			joinW(input[i], input[i] + 1);
		}
		else
		{
			joinH(input[i], input[i] + 1);
		}
	}
 
	for (int i = 0; i < n; i++)
	{
		cout << result[i] << endl;
	}
 
    return 0;  
}

 

 

《极限切割》是当今国内市场首屈一指的套料计算软件。自2004年投放市场以来,不断改进创新,功能日趋完善,深受广大用户欢迎。这里简要介绍这款软件的主要特色,详细内容参见本网站其它相关介绍。 《极限切割》提供了许多可以选择的切割参数,涵盖了机械(金属平板、卷板、原板反算等)、家具、石材、玻璃、装修等行业常用的各类排料参数,是一款通用性非常好的排料软件。下图展示了部分切割参数,为提高操作效率,还有一部分切割参数分布在数据录入和计算环节。 《极限切割专业版》(矩形排料、型材排料) 专门针对矩形材料排料,支持一刀切,特别适合玻璃切割、门窗加工、板式家具开料、金属剪板机作业、石材切割等生产领域。 《极限切割数控版》(数控玻璃切割机专用) 针对数控玻璃切割设备,支持矩形、异型玻璃切割。目前已经在贝佳莱(奥地利)、济南德佳玻璃机器有限公司采用。 《极限切割工业版》(异型材料切割) 针对异型零件套料开发的优化计算软件,计算速度和材料利用率都达到国际先进水准。支持AutoCad,可用于各类等离子切割、激光切割、火焰切割设备。 《极限工厂》——中小企业ERP系统 针对中小企业的特点,提供包括进、销、存、生产管理、套料计算的一体化的管理系统。即可弹机运行,也可运行在网络环境。 套料,排料,裁板,型材下料,板材优化,玻璃切割,开料,算料,省料,切割玻璃切割排料优化,坯材开料下料优化,板材切割开料下料套料优化,板材数控切割优化,异型套料优化计算
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值