hdu 4056 Draw a Mess -并查集+滑动法
来源:互联网 发布:php curl 输出图片 编辑:程序博客网 时间:2024/05/02 02:23
http://acm.hdu.edu.cn/showproblem.php?pid=4056
题意:给n*m的格点 (n=200,m=5e5)
q次操作,每次按 四个几何图形 的面积去覆盖格点 ,每个图形带有一个颜色C (q=5e5,C=[1-9])
问最后q次操作完成后,每种颜色的格子有多少个,输出9个数
可以知道,颜色会覆盖,因此,从最后面开始处理,如果当前要涂色的格子未涂色,则这个格子最终必定是当前要涂的色,同理如果当前格子已经有色,则需要忽略。
现在问题是怎么处理涂色操作?
由于行很少,可以暴力按行涂色,也即把该几何图形要覆盖的每一行都遍历,对于每行,用并查集去维护一个 大小为M的列:
维护一个father数组,fa[x]指的是x这个位置起,到达下一个可被涂色的位置-1,
维护一个vis数组,vis[x]=1,表示该位置已经涂色,=0则未涂色
假如图形X在 第i行的涂色范围是第L列到第R列,则
l=max (l,0); r=min(r,m-1); int fx=find(l); for (int i=r; i>=l;) { int fy=find(i);<span style="white-space:pre"></span>//找到最左的可涂色位置 if (!vis[fy]) ans[col]++;<span style="white-space:pre"></span>//可涂色 vis[fy]=1;<span style="white-space:pre"></span>//标记已涂色 if (fx!=fy) fa[fy]=fx;<span style="white-space:pre"></span>//更新 【最左可涂色位置】 i=fy-1;<span style="white-space:pre"></span>//继续滑动 }
#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <map>#include <set>#include <vector>#include <iostream>using namespace std;const double pi=acos(-1.0);double eps=0.000001;int fa[51234];int vis[51234];int find(int x){ if (fa[x]==x) return x; else return fa[x]=find(fa[x]);}struct node{ char op[12]; int x,y,z,d; int e; node() {}};node tm[51234];int ans[10];int main(){ int n,m,k; while(scanf("%d%d%d",&n,&m,&k)!=EOF) { memset(ans,0,sizeof ans); for (int i=1; i<=k; i++) { scanf("%s%d%d%d%d",tm[i].op,&tm[i].x,&tm[i].y,&tm[i].z,&tm[i].d); if (tm[i].op[0]=='R') scanf("%d",&tm[i].e); } for (int j=0; j<n; j++) { for (int i=0; i<=m; i++) fa[i]=i,vis[i]=0; for (int i=k; i>=1; i--) { int l,r,col=tm[i].d; if (tm[i].op[0]=='C') { int up=tm[i].x+tm[i].z; int down=tm[i].x-tm[i].z; if (!(j>=down&&j<=up ))continue; int tmp=tm[i].z*tm[i].z-(tm[i].x-j)*(tm[i].x-j); tmp=sqrt(tmp); l=tm[i].y-tmp; r=tm[i].y+tmp; } if (tm[i].op[0]=='D') { int up=tm[i].x+tm[i].z; int down=tm[i].x-tm[i].z; if (!(j>=down&&j<=up ))continue; l=tm[i].z-abs(j-tm[i].x); r=tm[i].y+l; l=tm[i].y-l; } if (tm[i].op[0]=='R') { col=tm[i].e; int up=tm[i].x+tm[i].z-1; int down=tm[i].x; if (!(j>=down&&j<=up ))continue; l=tm[i].y; r=tm[i].y+tm[i].d-1; } if (tm[i].op[0]=='T') { int up=tm[i].x+(tm[i].z+1)/2-1; int down=tm[i].x; if (!(j>=down&&j<=up ))continue; int tmp=(tm[i].z-1)/2+(tm[i].x-j); l=tm[i].y-tmp; r=tm[i].y+tmp; } l=max (l,0); r=min(r,m-1); int fx=find(l); for (int i=r; i>=l;) { int fy=find(i); if (!vis[fy]) ans[col]++; vis[fy]=1; if (fx!=fy) fa[fy]=fx; i=fy-1; } } } for (int i=1; i<=9; i++) { if (i>1) printf(" "); printf("%d",ans[i]); } printf("\n"); } return 0;}
0 0
- hdu 4056 Draw a Mess -并查集+滑动法
- hdu 4056 Draw a Mess(并查集)
- hdu 4056 Draw a Mess(数据结构-并查集)
- HDU 4056 Draw a Mess(并查集)
- UVA1493 - Draw a Mess(并查集)
- UVA 1493 - Draw a Mess(并查集)
- uva 1493 - Draw a Mess(并查集)
- uva1493 - Draw a Mess 并查集路径压缩
- UVA 1493 Draw a Mess(并查集+set)
- UVA - 1493 Draw a Mess 并查集+压缩图
- hdc 4056 Draw a Mess(路径压缩)
- 2011ACM/ICPC亚洲区大连现场赛:F Draw a Mess [zoj 3544 Draw a Mess]
- 并查集Hdu 1829 A Bug's Life
- HDU 1325 Is It A Tree?(并查集)
- hdu 1325 Is It A Tree?(并查集)
- HDU 1829 A Bug's Life 并查集
- hdu 1829 A Bug's Life(并查集)
- HDU 1829 A Bug's Life(并查集)
- Get,Post和Request
- POJ 3436 ACM Computer Factory(最大流)
- 提高项目30.3-删除特定字符
- hdu1556
- centos彻底删除文件夹、文件命令(centos 新建、删除、移动、复制等命令)
- hdu 4056 Draw a Mess -并查集+滑动法
- Java实现敏感词过滤
- 超漂亮Js+css图片幻灯切换
- C# 解决winform界面闪屏问题及弊端
- 数据结构与算法简记:根据层次顺序存储结构构建二叉树
- vector 排序使用方式
- UITableViewCell去掉点击效果
- 第二十六章、MVP应用构架模式
- 纯CSS代码实现的图片列表滚动