51Nod-1562-玻璃切割
来源:互联网 发布:java jdbc mysql 编辑:程序博客网 时间:2024/05/01 19:47
首先推荐这位大大的博客,我是看他的博客看懂的:
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 玻璃切割 (set)
- 51nod 1562 玻璃切割 【线段树】
- 51nod-1562:玻璃切割(O(n)模拟)
- 51nod 1562 玻璃切割(线段树区间合并)
- 51nod 1562玻璃切割(降维,反向处理)
- 51nod 1562 玻璃切割 (set+离线处理)
- 51nod 1562 玻璃切割 (STL map+一点点的思考)
- 玻璃切割
- 51nod1562-模拟&好题&链表|线段树-玻璃切割
- 51Nod
- 51Nod
- 51nod
- 51Nod
- 51Nod
- 51Nod
- 程序的预编译,编译,汇编,链接过程
- JAVA求学之路重写Converter
- windows文件及目录常用操作命令
- Hash Perfectly UESTC
- 在有生之年,还能看到哪些改变世界的黑科技产品?
- 51Nod-1562-玻璃切割
- LeetCode087 Scramble String
- Android 应用程序数据持久化方法
- 【SDOI2017】硬币游戏
- Oracle 如何合并某字段的值
- qnx的ssh功能配置,nfs配置,scp配置,telnet配置
- 第四章预习
- openshift registry固定ip不更新问题解决
- Struts2.5版本以上的struts.xml配置