Bee Problem(DFS)

Bee Problem(DFS)

You are a busy little bee, and you have a problem. After collecting nectar all day long, you are returning to the beehive with a large supply of honey. You would really like to take a nap now, but sadly, you have to store all the honey in your beehive first. Opening up a cell in the hive to funnel honey into takes a lot of time, so you want to avoid doing this as much as possible.

Some of the cells in the beehive are already filled with old, hardened honey. The other cells are still empty. If you pour honey into an empty cell, it automatically starts flowing into adjacent empty cells. From these cells, the honey again flows to other neighbouring empty cells, and so on. This saves you from having to funnel honey into them directly. You decide to use this to your advantage, by pouring into cells with lots of (indirect) adjacent open cells.

在这里插入图片描述

Figure 1: The beehives from the first two samples. The black hexagons
already contain hardened honey. The white cells are still empty.

You have some units of honey, and know the layout of your beehive. By cleverly choosing which cells to funnel honey into, what is the minimal amount of work you have to do?

Input
The input starts with three integers, 0≤h≤106, the amount of honey you have, and 1≤n,m≤103, the dimensions of the grid.

Then follow n lines, one for each row of the grid. Each row has m symbols, either ., representing an empty cell, or #, representing a filled cell. These symbols are separated by spaces. Furthermore, every second row starts with a space, as these are slightly offset to the right.

The grid always has enough open cells to store all your honey.

Output
Output a single integer, the number of cells you have to funnel honey into directly to store all your honey in the hive.

在这里插入图片描述

本题难度在于存值,并且思路一定要清晰,否则极有可能出错。

  • 首先 ,本题和一般的DFS有区别,因为本题是六边形的格子,所以可以看出:
    偶数行的格子不能往斜右走,奇数行格子不能往斜左走。

当然,我刚开始并不是这样写的,我使用了N*2M的方格,直接构造成六边形的样子,但很遗憾,数据只能过去一半,并且我还没找出原因,等会先贴出过不去的代码,再贴AC代码。

  • 其次, 计数需要很强的逻辑思维,否则,很容易出现各种各样的问题。时间超时或者答案错误。

先贴出问题代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
char visit[10005][10005];
long long int n, m;
long long int sun,sum;
long long int a[100005];
long long int z = -1;
long long int f[6][2] = { {-1,1},{1,1},{0,2},{0,-2},{-1,-1},{1,-1} };
long long int cmp(long long int a, long long int b)
{
	return a > b;
}
bool check(long long int x, long long int y)
{
	if (x >= 1 && x <= n && y >= 1 && y <= m)
		return true;
	return false;
}
void dfs(long long int x,long long int y)
{
	a[z] = sum;
	visit[x][y] = '#';
	for (long long int i = 0; i < 6; i++)
	{
		if (check(x+f[i][0], y+f[i][1]) && visit[x+f[i][0]][y+f[i][1]] == '.')
		{
			sum++;
			//cout << "*" << x + f[i][0] << " " << y + f[i][1] << endl;
			dfs(x + f[i][0], y + f[i][1]);
		}
	}
}
int main()
{
	long long  int cnt = 0;
	cin >> sun >> n >> m;
	m = 2 * m;
	for (long long int i = 1; i <= n; i++)
	{
		for (long long int j = 1; j <= m; j = j + 2)
		{
			if (i % 2 == 1)
			{
				cin >> visit[i][j];
				visit[i][j +1] = ' ';
			}
			else
			{
				visit[i][j] = ' ';
				cin >> visit[i][j+1];
			}

		}
	}
	m = m + 2;
	/*for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; j++)
			printf("%c", visit[i][j]);
		cout << endl;
	}*/

	for (long long int i = 1; i <= n; i++)
		for (long long int j = 1; j <= m; j++)
		{
			if (visit[i][j] == '.')
			{
				//cout << "**" << i << " " << j << endl;
				sum = 1;
				z++;
				cnt++;
				dfs(i, j);
			}
		}
	sort(a, a + cnt,cmp);
	long long int p = 0, s = 0;
	
	/*for (long long int i = 0; i < cnt; i++)
		cout << a[i] << endl;*/
		for (long long int i = 0; i <=cnt; i++)
		{
			if (s >= sun)
				break;
			s = s + a[i];
			p++;
		}
		printf("%lld\n", p);
	return 0;
}

再贴出AC代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
char visit[10005][10005];
long long int n, m;
long long int sun, sum;
long long int a[1000005];
long long int z = 0;
int mov1[6][2] = { 1,0,-1,0,0,1,0,-1,-1,1,1,1 };//右 
int mov2[6][2] = { 1,0,-1,0,0,1,0,-1,1,-1,-1,-1 };//左
long long int cmp(long long int a, long long int b)
{
	return a > b;
}
bool check(long long int x, long long int y)
{
	if (x >= 1 && x <= n && y >= 1 && y <= m)
		if (visit[x][y] == '.')
			return true;
	return false;
}
void dfs(long long int x, long long int y)
{
	sum++;
	visit[x][y] = '#';
	for (long long int i = 0; i < 6; i++)
	{
		if (x % 2 == 0)
		{
			if (check(x + mov1[i][0], y + mov1[i][1]))
				dfs(x + mov1[i][0], y + mov1[i][1]);
		}
		else
			if (check(x + mov2[i][0], y + mov2[i][1]))
				dfs(x + mov2[i][0], y + mov2[i][1]);
	}
	return;
}
int main()
{
	cin >> sun >> n >> m;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			cin >> visit[i][j];
	/*	for (int i = 1; i <= n; i++)
		{
			for (int j = 1; j <= m; j++)
				printf("%c", visit[i][j]);
			cout << endl;
		}*/
	for (long long int i = 1; i <= n; i++)
		for (long long int j = 1; j <= m; j++)
		{
			if (visit[i][j] == '.')
			{
				sum = 0;
				dfs(i, j);
				a[z++] = sum;
			}
		}
	sort(a, a + z, cmp);
	long long int p = 0, s = 0;

	/*for (long long int i = 0; i <=z; i++)
		cout << a[i] << endl;*/

	for (long long int i = 0; i <= z; i++)
	{
		if (s >= sun)
			break;
		s = s + a[i];
		p++;
	}
	printf("%lld\n", p);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值