Describe
多组测试t
输入一个map大小X * Y,map中有n个障碍点,输入n个障碍点的坐标,问map有几个连通块
Solution
如果地图不大完全可以dfs/bfs去做,但是X,Y【1,1e9】就需要进行离散化
可见障碍点n很少,最多200个
输入完障碍点后,分x,y轴进行离散处理
排序后去除一维坐标重合的点,然后进行离散处理,障碍点间(包括障碍点和边界之间)距离大于1才进行离散,然后还要分配每个障碍点坐标并进行记录
x,y轴离散完毕后,进行新地图的映射,主要是障碍点的映射
然后bfs四处搜索就可以了
一共需要存储:
整型:
X,Y 地图大小
n 障碍点大小
ans 连通块个数
数组:
Pair P 初始障碍点坐标
sorted_X,sorted_Y 包含边界点的 排号序的一维映射
cpl_X,cpl_y 映射好的一维坐标
new_mp 映射好的新地图
ret 每个连通块的大小
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 210 * 2;
int X,Y,n;
pair<int,int> p[maxn];
int x[maxn],y[maxn];
int ls_x[maxn];
int ls_y[maxn];
int new_mp[maxn][maxn];
int x_num,y_num;
ll ans[maxn*maxn];
int ret;
void dfs(int a,int b){
ans[ret] += (ll)ls_x[a] * ls_y[b];
new_mp[a][b] = 1;
if(a > 0 && !new_mp[a-1][b])dfs(a-1,b);
if(a < x_num - 1 && !new_mp[a+1][b])dfs(a+1,b);
if(b > 0 && !new_mp[a][b-1])dfs(a,b-1);
if(b < y_num-1 && !new_mp[a][b+1])dfs(a,b+1);
}
int main()
{
int t;
scanf("%d",&t);
for(int cas = 1;cas <= t;++cas){
scanf("%d%d",&X,&Y);
scanf("%d",&n);
//把范围扩大1,防止边界有障碍物
x[0] = y[0] = 0;
x[1] = X + 1;
y[1] = Y + 1;
for(int i = 1;i <= n;++i){
scanf("%d%d",&p[i].first,&p[i].second);
x[i+1] = p[i].first;
y[i+1] = p[i].second;
}
int cnt;
sort(x,x+n+2);
cnt = unique(x,x+n+2) - x;
x_num = 0;
for(int i = 1;i < cnt;++i){
if(x[i] - x[i-1] > 1)ls_x[x_num++] = x[i] - x[i-1] - 1;
if(i != cnt-1)ls_x[x_num++] = 1;
for(int j = 1;j <= n;++j){
if(p[j].first == x[i]){
p[j].first = x_num-1;
//break;
}
}
}
sort(y,y+n+2);
cnt = unique(y,y+n+2) - y;
y_num = 0;
for(int i = 1;i < cnt;++i){
if(y[i] - y[i-1] > 1)ls_y[y_num++] = y[i] - y[i-1] - 1;
if(i != cnt-1)ls_y[y_num++] = 1;
for(int j = 1;j <= n;++j){
if(p[j].second == y[i]){
p[j].second = y_num-1;
//break;
}
}
}
for(int i = 0;i < x_num;++i){
for(int j = 0;j < y_num;++j){
new_mp[i][j] = 0;
}
}
for(int i = 1;i <= n;++i)
new_mp[p[i].first][p[i].second] = 1;
ret = 0;
memset(ans,0,sizeof(ans));
for(int i = 0;i < x_num;++i){
for(int j = 0;j < y_num;++j){
if(!new_mp[i][j]){
ret++;
dfs(i,j);
}
}
}
sort(ans+1,ans+1+ret);
printf("Case #%d:\n%d\n",cas,ret);
for(int i = 1;i <= ret;++i){
if(i == 1)printf("%I64d",ans[i]);
else printf(" %I64d",ans[i]);
}
printf("\n");
}
return 0;
}