1.题目链接。题目大意就是给了一个图,图上有一些障碍,这些障碍把图分成了几个块,求每一个块中点的数量。因为这个图很大,达到了1e9,但是点很少,只有200个左右,所以需要压缩这个图。也就是离散化,然后dfs即可。离散化操作其实就是一个二维的离散化,对x,y分别做一下一维离散化就行了。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#pragma warning(disable:4996)
struct point
{
ll x, y;
};
int vis[500][500];
vector<ll>nx, ny;
int dir[4][2] = { 1,0,-1,0,0,1,0,-1 };
ll sum;
void dfs(int i, int j)
{
if (vis[i][j] || i >= nx.size() || i<0 || j>=ny.size() || j < 0)return;
sum += nx[i] * ny[j];
vis[i][j] = 1;
for (int t = 0;t < 4; t++)
{
int dx = i+dir[t][0];
int dy = j+dir[t][1];
dfs(dx, dy);
}
}
int main()
{
int T;
scanf("%d", &T);
for (int ca = 1; ca <= T; ca++)
{
ll c, r;
scanf("%lld%lld", &c, &r);
ll q;
scanf("%lld", &q);
vector<point>pos(q);
for (int i = 0; i < q; i++)
{
scanf("%lld %lld", &pos[i].y, &pos[i].x);
}
printf("Case #%d:\n", ca);
vector<ll>vecx;
vector<ll>vecy;
vecx.push_back(0);
vecx.push_back(r);
vecy.push_back(0);
vecy.push_back(c);
for (int i = 0; i < q; i++)
{
vecx.push_back(pos[i].x);
vecy.push_back(pos[i].y);
}
sort(vecx.begin(), vecx.end());
sort(vecy.begin(), vecy.end());
int numx = unique(vecx.begin(), vecx.end()) - vecx.begin();
int numy = unique(vecy.begin(), vecy.end()) - vecy.begin();
nx.clear(), ny.clear();
map<ll, ll>mx, my;
for (int i = 1; i < numx; i++)
{
if (vecx[i] - vecx[i - 1] > 1)nx.push_back(vecx[i] - vecx[i - 1] - 1);
nx.push_back(1);
mx[vecx[i]] = nx.size() - 1;
}
for (int j = 1; j < numy; j++)
{
if (vecy[j] - vecy[j - 1] > 1)ny.push_back(vecy[j] - vecy[j - 1] - 1);
ny.push_back(1);
my[vecy[j]] = ny.size() - 1;
}
memset(vis, 0, sizeof(vis));
for (int i = 0; i < q; i++)
{
vis[mx[pos[i].x]][my[pos[i].y]] = 1;
}
vector<ll>ans;
for (int i = 0;i < nx.size(); i++)
{
for (int j = 0; j < ny.size(); j++)
{
sum = 0;
if (!vis[i][j])
dfs(i, j);
if (sum)
ans.push_back(sum);
}
}
sort(ans.begin(), ans.end());
printf("%d\n", ans.size());
for (int i = 0; i < ans.size(); i++) {
if (i)printf(" %lld", ans[i]);
else printf("%lld", ans[i]);
}
printf("\n");
}
return 0;
}
/*
3 3
2
1 2
2 1
1 0 1
0 1 1
1 1 1
*/