【HDU 5925】Coconuts

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

 */

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值