hiho 1487 并查集+搜索 [Offer收割]编程练习赛11 problem C 岛屿3
来源:互联网 发布:全网通手机淘宝 编辑:程序博客网 时间:2024/05/21 14:03
#1487 : 岛屿3
- 样例输入
3 0 0 1 1 1 0
- 样例输出
1 1 4 2 2 8 1 3 8
描述
H国正在进行一项持续N周的填海造岛工程。整片工程海域可以被看作是1000x1000的网格。
每周都有一块1x1的单位方格海域被填成陆地。如果我们将连成一片的陆地(一块单位方格与它上下左右4个单位方格是相连的)视为岛屿,H国想监测每周末整片海域中一共存在有多少个岛屿,以及这些岛屿的总面积和总周长各是多少。
假设工程持续三周,第一周被填的海域坐标是(0, 0),那么第一周结束后有1座岛屿、总面积是1、总周长是4:
#........
第二周被填的海域坐标是(1, 1),那么第二周结束后有2座岛屿、总面积是2、总周长是8:
#...#....
第三周被填的海域坐标是(1, 0),那么第三周结束后有1座岛屿、总面积是3、总周长是8:
#..##....
你能完成这项任务么?
输入
第一行包含一个整数N,表示工程持续的周数。(1 <= N <= 100000)
以下N行每行包含两个整数x和y,表示当周被填的海域坐标。(0 <= x, y < 1000)
输出
输出N行,每行包含3个整数,依次是当周末岛屿的数量、总面积和总周长。
题意非常简单,1000*1000的矩阵,一开始是空的,每次不重复的放一个点,求4向联通集的个数,总面积和总周长。
这里联通集我们用并查集处理一下,二维的点集,可以把x,y映射到1000x+y上构成一维的。因为xy范围都在1000内,用并查集以便于统计联通集的个数,每次放入一个新块之后,把周边的相邻的点都先存到一个vector里,然后挨着判断一下是不是一个集合,如果不是一个集合,那么联通集总数就要-1,如果不相邻,总数就+1,新增周长可以用4-2*相邻的边数来计算。
这个题调试了半天,2.30比赛结束,我2.31提交上去1A了,T_T。问题出在我这一堆for循环上,有一个地方手抖敲错了。。。for(int k=0;k<4;i++),我调了将近半个小时,就是没看出来哪里不对,程序运行到这就卡住了,比赛结束的一瞬间我把i改成k交上去就A了。天命如此……自己太水,不想说什么了,这又让我想起来几次区域赛打铁的经历,跟这次大同小异,有毒呀。
#include <iostream>#include <stdio.h>#include <math.h>#include <stdlib.h>#include <string>#include <string.h>#include <algorithm>#include <vector>#include <queue>#include <set>#include <map>#include <stack>using namespace std;//x*1000+y;int par[1000005];int tall[1000005];void init(int n){ for(int i=1;i<=n;i++){ par[i]=i; tall[i]=0; }}int find_root(int x){ if(par[x]==x){ return x; } else{ return par[x]=find_root(par[x]); }}void unite(int x,int y){ x=find_root(x); y=find_root(y); if(x==y)return; if(tall[x]<tall[y]){ par[x]=y; } else{ par[y]=x; if(tall[x]==tall[y])tall[x]++; }}bool same(int x,int y){ return find_root(x)==find_root(y);}int F[1005][1005];int d[4][2]={1,0,0,1,0,-1,-1,0};int n;bool cango(int x,int y){ return x>=0&&x<1000&&y>=0&&y<1000;}int main(){ while(cin>>n){ memset(F,0,sizeof(F)); init(1000009); int num=0;//数量 int S=0;//面积 int L=0;//周长 for(int i=0;i<n;i++){ int x,y; scanf("%d%d",&x,&y); F[x][y]=1; int V=x*1000+y+1; int find_a_new=1;//四周都是空的 int chongbian=0;//重合边数量 vector<int>P;//所有边界点 P.clear(); for(int k=0;k<4;k++){ int nx=x+d[k][0]; int ny=y+d[k][1]; if(cango(nx,ny)){ int nV=nx*1000+ny+1; if(F[nx][ny]==1){ P.push_back(nV); chongbian++; find_a_new=0;//没找到新的 if(same(nV,V)){ //chongbian++; //unite(nV,V); } else{ //unite(nV,V); //chongbian++; } } else{ } } else{ } // cout<<"fuck"<<endl; } if(find_a_new==1){ num++; L+=4; } else{ unite(P[0],V); // cout<<"stat "<<P.size()<<endl; //cout<<P[0]<<" !!! "<<P[1]<<endl; for(int j=1;j<P.size();j++){ if(!same(P[j],P[j-1])){ num--; unite(P[j],P[j-1]); } } // cout<<"stat2"<<endl; L+=4-2*chongbian; } S++; cout<<num<<" "<<S<<" "<<L<<endl; } } return 0;}
- hiho 1487 并查集+搜索 [Offer收割]编程练习赛11 problem C 岛屿3
- hiho 1638 小Hi的天平 [Offer收割]编程练习赛36 Problem B 并查集+图dfs乱搞
- hiho 1485 尺取法 [Offer收割]编程练习赛11 problem A hiho字符串
- hiho 1601 背包DP乱搞 [Offer收割]编程练习赛29 Problem C 最大得分
- hiho 1613 墨水滴 [Offer收割]编程练习赛32 Problem C 优先队列+BFS
- hiho 1617 方格取数 [Offer收割]编程练习赛33 Problem C DP
- hiho 1625 重复字符串匹配 [Offer收割]编程练习赛35 Problem C KMP模板题
- hiho 1486 DP+状压 [Offer收割]编程练习赛11 problem B 物品价值
- hiho 1620 股票价格3 [Offer收割]编程练习赛34 Problem B 单调栈
- hiho[Offer收割]编程练习赛1
- hiho 1599 dfs乱搞 [Offer收割]编程练习赛29 Problem A 逃离迷宫4
- hiho 1611 气泡图 [Offer收割]编程练习赛32 Problem A 数学公式暴力
- hiho 1612 候选人追踪 [Offer收割]编程练习赛32 Problem B 乱搞
- hiho 1615 矩阵游戏II [Offer收割]编程练习赛33 Problem A 贪心暴力
- hiho 1619 “共同富裕” [Offer收割]编程练习赛34 Problem A 数学
- hiho 1623 有歧义的号码 [Offer收割]编程练习赛35 Problem A
- hiho 1624 最短游览路线 [Offer收割]编程练习赛35 Problem B
- hiho 1626 缩写命名 [Offer收割]编程练习赛35 Problem D 二分图匹配
- 用Java处理JSON 二
- 浅谈Android模块化设计(模块化的一些思考)
- 在O(1)时间复杂度删除链表节点
- picasso-强大的Android图片下载缓存库
- 删除链表中的元素
- hiho 1487 并查集+搜索 [Offer收割]编程练习赛11 problem C 岛屿3
- 第二章图像处理
- [编程题] 简单错误记录
- leetcode-120. Triangle
- c#中List<>类的Sort()的几种形式
- JavaScript中的Number类型、String类型、Global对象、Math对象总结
- ASP创建数据库,新建数据表、字段
- Debug---Eclipse断点调试基础
- HCNA-Cloud云计算认证