您的位置:首页 > 其它

51Nod-1562-玻璃切割

2017-04-21 22:20 218 查看
首先推荐这位大大的博客,我是看他的博客看懂的:

http://blog.csdn.net/f_zyj/article/details/68939756

问题描述:

现在有一块玻璃,是长方形的(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

挺神奇的一道题,开始是用链表总,超时,然后看评论说用IO挂,多交几次有一定几率过(看人品··)。。。



然后看到网上第二种思路,用并查集来做,首先如何用并查集来表示一个区间,将点i和i+1合并,并且将他们的权值也合并,如果在某点进行了分割,就不将该点进行合并操作,然后先把每个切割线记录下来,做一次处理,得到的并查集就是对N次切割完得到的情况,接着倒着来,把每次切割的点j,与j+1进行合并操作,并合并他们的权值,同时更新最大的宽和高,再把答案存起来,最后输出。

#include<bits/stdc++.h>
using namespace std;
const long long maxn=2e5+10;

long long mx[2];
long long par[2][maxn];
long long rankpar[2][maxn];
long long vis[2][maxn];
vector<pair<char,long long> >input;

long long w,h,n;

long long find(long long k,long long z)
{
return par[z][k]=(par[z][k]==k?k:find(par[z][k],z));
}

void join(long long x,long long y,long long z)
{
long long xx=find(x,z);
long long yy=find(y,z);
par[z][xx]=yy;
rankpar[z][yy]+=rankpar[z][xx];
mx[z]=max(mx[z],rankpar[z][yy]);
}

void init()
{
for(long long i=0;i<2;i++)
{
for(long long j=0;j<maxn;j++)
{
par[i][j]=j;
rankpar[i][j]=1;
}
}
}

int main()
{
cin>>w>>h>>n;
memset(vis,0,sizeof(vis));
pair<char,long long> p;
mx[0]=mx[1]=1;
init();
for(long long i=0;i<n;i++)
{
getchar();
p.first=getchar();
scanf("%d",&p.second);
input.push_back(p);
if(p.first=='H')
vis[0][p.second]=1;
else
vis[1][p.second]=1;
}
for(long long i=1;i<h;i++)
{
if(!vis[0][i])
join(i,i+1,0);
}
for(long long i=1;i<w;i++)
{
if(!vis[1][i])
join(i,i+1,1);
}
stack<long long> ans;
ans.push(mx[0]*mx[1]);
for(long long i=n-1;i>=0;i--)
{
if(input[i].first=='H')
join(input[i].second,input[i].second+1,0);
else
join(input[i].second,input[i].second+1,1);
ans.push(mx[0]*mx[1]);
}
ans.pop();
while(!ans.empty())
{
cout<<ans.top()<<endl;
ans.pop();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: