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进行合并操作,并合并他们的权值,同时更新最大的宽和高,再把答案存起来,最后输出。
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(); } }
相关文章推荐
- 51Nod-1562-玻璃切割
- 51nod 1562 玻璃切割(线段树区间合并)
- 51nod 1562 玻璃切割
- 51nod-1562:玻璃切割(O(n)模拟)
- 51Nod 1562 玻璃切割 (set)
- 51nod 1562玻璃切割(降维,反向处理)
- 51nod 1562 玻璃切割
- AC日记——玻璃切割 51nod 1562
- 51nod 1562 玻璃切割 (STL map+一点点的思考)
- 51nod 1562 玻璃切割 【线段树】
- 玻璃切割
- 51nod1562-模拟&好题&链表|线段树-玻璃切割
- 51nod 1268 和为K的组合
- 51Nod 1264:线段相交(计算几何)
- 51nod 1136 欧拉函数
- 51nod 1099 任务执行顺序(贪心)
- 【51Nod 1806】wangyurzee
- 51nod-1227-平均最小公倍数
- 51nod 1094
- 51Nod-1019-逆序数