D - Coconuts
题 意:给你一个R*C的矩阵,有K堵墙,问你有几个联通快,每个联通块的元素是多少?
数据范围:
1<=R,C<=1e9
0<=k<=200
输入样例:
2
3 3
2
1 2
2 1
3 3
1
2 2
输出样例:
Case #1:
2
1 6
Case #2:
1
8
思 路 :因为墙很少,离散化,把可以浓缩的格子浓缩,记录一下宽度就好了,也就是说把可以离散化的格子离散化成一个格子,记录一下矩形的长和宽就好了。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn = 500+5;
map<int,int> mpx,mpy;
int xx[maxn],yy[maxn];
int vis[maxn][maxn];
int mp[maxn][maxn];
ll val[maxn];
ll vx[maxn],vy[maxn];
int n,m,k;
struct node{
int x,y;
}a[maxn];
struct Em{
int x,y;
int color;
};
int to[4][2] = {-1,0,1,0,0,-1,0,1};
queue<Em > que;
void init(){
while(!que.empty())que.pop();
mpx.clear();mpy.clear();
memset(xx,0,sizeof(xx));
memset(yy,0,sizeof(yy));
memset(vx,0,sizeof(xx));
memset(vy,0,sizeof(vy));
memset(vis,0,sizeof(vis));
memset(mp,0,sizeof(mp));
memset(val,0,sizeof(val));
}
int main(){
int t,Kase=1;
scanf("%d",&t);
while(t--){
init();
scanf("%d %d",&n,&m);
scanf("%d",&k);
int num1 = 1,num2 = 1;
for(int i=1;i<=k;i++){
int x,y;
scanf("%d %d",&x,&y);
a[num1].x = x;
a[num2].y = y;
xx[num1++] = x;
yy[num2++] = y;
}
xx[num1++]=0;xx[num1++]=n+1;yy[num2++]=0;yy[num2++]=m+1;
sort(xx+1,xx+num1);
sort(yy+1,yy+num2);
num1 = unique(xx+1,xx+num1)-(xx+1);
num2 = unique(yy+1,yy+num2)-(yy+1);
int pre=1,hang=1,lie=1;
for(int i=1;i<=num1;i++){
if(i!=1 && xx[i]!=pre+1) vx[hang]=xx[i]-pre-1,hang++;
vx[hang]=1;
pre = xx[i];
mpx[xx[i]]=hang++;
}
pre=1;
for(int i=1;i<=num2;i++){
if(i!=1 && yy[i]!=pre+1)vy[lie]=yy[i]-pre-1,lie++;
vy[lie]=1;
pre=yy[i];
mpy[yy[i]]=lie++;
}
hang-=2;lie-=2;
for(int i=1;i<=hang+1;i++)for(int j=1;j<=lie+1;j++)mp[i][j]=1;
for(int i=2;i<=hang;i++)for(int j=2;j<=lie;j++)mp[i][j]=0,vis[i][j]=0;
for(int i=1;i<=k;i++){
int temp1 = mpx[a[i].x],temp2 = mpy[a[i].y];
mp[temp1][temp2] = 1;
}
int color=0;
for(int i=2;i<=hang;i++){
for(int j=2;j<=lie;j++){
if(mp[i][j] == 1 || vis[i][j] == 1) continue;
color++;
Em em;em.x = i;em.y = j;em.color = color;
vis[em.x][em.y]=1;
que.push(em);
while(!que.empty()){
Em emq;emq = que.front();que.pop();
val[emq.color] += vx[emq.x]*vy[emq.y];
for(int i=0;i<4;i++){
int fx = emq.x + to[i][0],fy = emq.y+to[i][1];
if(fx>=2 && fx<=hang && fy>=2 && fy<=lie && mp[fx][fy]!=1 && !vis[fx][fy] ){
Em _em;_em.x = fx;_em.y=fy;_em.color = color;
vis[_em.x][_em.y] = 1;
que.push(_em);
}
}
}
}
}
sort(val+1,val+color+1);
printf("Case #%d:\n",Kase++);
printf("%d\n",color);
for(int i=1;i<=color;i++){
printf("%I64d%c",val[i],i==color?'\n':' ');
}
}
return 0;
}
/*
100
5 5
4
2 3
3 2
3 4
4 3
*/
//