题意:就是给你一个图有多少连通块,按增序输出,但是图比较大需要离散化一下。
思路:把不存在障碍物的行与列压缩为一行或者一列,然后存在的就不压缩原样记录,压缩后的就记录原来的行列大小,这样行列最大就300了就可以了正常dfs了
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
bool st[M][M];
int n, m, k;
PII p[N];
vector<int> lenx, leny;
map<int, int> cntx, cnty;
int x[N], y[N];
int cnt1, cnt2;
vector<int> ans;
int sum;
void dfs(int x, int y)
{
st[x][y] = 1;
sum += lenx[x] * leny[y]; // 这样好点都变成矩形了
for (int i = 0; i < 4; i++)
{
int xx = x + dx[i];
int yy = y + dy[i];
if (xx < 0 || xx >= lenx.size() || yy < 0 || yy >= leny.size() || st[xx][yy])
continue;
dfs(xx, yy);
}
}
void solve()
{
cin >> n >> m;
ans.clear();
lenx.clear();
leny.clear();
cntx.clear();
cnty.clear();
cnt1 = 0, cnt2 = 0;
memset(st, 0, sizeof st);
x[cnt1++] = y[cnt2++] = 0; // 设置两个边界
x[cnt1++] = n;
y[cnt2++] = m;
cin >> k;
for (int i = 1; i <= k; i++)
{
cin >> p[i].xx >> p[i].yy;
x[cnt1++] = p[i].xx;
y[cnt2++] = p[i].yy;
}
sort(x, x + cnt1); // 离散化坐标
sort(y, y + cnt2);
cnt1 = unique(x, x + cnt1) - x;
cnt2 = unique(y, y + cnt2) - y;
for (int i = 1; i < cnt1; i++)
{
int len = x[i] - x[i - 1];
if (len > 1)
lenx.pb(len - 1); // 可以压缩的行
lenx.pb(1); // 坏点不可压缩,记录这一行原本的宽度
cntx[x[i]] = lenx.size() - 1; // 记录这个点离散化的坐标,下标从0开始
}
for (int i = 1; i < cnt2; i++)
{
int len = y[i] - y[i - 1];
if (len > 1)
leny.pb(len - 1); // 可以压缩的列
leny.pb(1); // 坏点不能压缩,记录这一列原本的宽度
cnty[y[i]] = leny.size() - 1; // 记录这个点离散化的坐标,下标从0开始
}
for (int i = 1; i <= k; i++)
{
st[cntx[p[i].xx]][cnty[p[i].yy]] = 1; // 坏点标记为1不再遍历
}
for (int i = 0; i < lenx.size(); i++)
{
for (int j = 0; j < leny.size(); j++)
{
if (!st[i][j]) // 遍历一次一个块
{
sum = 0;
dfs(i, j);
ans.pb(sum);
}
}
}
sort(ans.begin(), ans.end());
cout << ans.size() << endl;
for (auto ed : ans)
cout << ed << ' ';
cout << endl;
}