题目
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,主要是要解决点移动的问题,因为它是蜂巢状的,所以不能简单当作矩形方格处理,由于我是把原图消去空格再直接存入二维数组中,所以要考虑奇偶问题,边%2等于0和边%2等于1时的移动有所不同所以我用三维数组存移动坐标解决,然后直接DFS遇到“.”就将它换成“#”,并且用数组依次记录每一块相邻点构成的空白区域中“.”的个数,数组大小即为空白区域的个数,之后将数组排序再和k比较即可.
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
char s[1005][2005];
int h,n,m;
int dir[2][6][2]={{{-1,-1},{0,-1},{-1,0},{1,0},{0,1},{1,-1}},
{{0,-1},{1,1},{-1,0},{1,0},{-1,1},{0,1}}};
int c[1000005];
int k=0,d;
bool cmp(int a,int b)
{
return a>b;
}
void dfs(int x,int y)
{
if(s[x][y]=='#'){
return ;
}
if(s[x][y]=='.') d++; //记录点的个数
s[x][y]='#';
if(x%2==0){
for(int i=0;i<6;i++){
int xx=x+dir[0][i][0];
int yy=y+dir[0][i][1];
if(s[xx][yy]=='.'&&xx>=0&&xx<n&&yy>=0&&yy<m){
dfs(xx,yy);
}
}
}
else{
for(int i=0;i<6;i++){
int xx=x+dir[1][i][0];
int yy=y+dir[1][i][1];
if(s[xx][yy]=='.'&&xx>=0&&xx<n&&yy>=0&&yy<m){
dfs(xx,yy);
}
}
}
}
int main()
{
cin>>h>>n>>m;
getchar();
for(int i=0;i<n;i++){
if(i%2==1) getchar();
for(int j=0;j<m;j++){
scanf("%c",&s[i][j]);
getchar();
}
}
memset(c,0,sizeof(c));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(s[i][j]=='.'){
d=0;
dfs(i,j);
c[k++]=d;
}
}
}
if(h==0){
cout<<"0"<<endl;
return 0;
}
sort(c,c+k,cmp);//排序重大到小
int i;
for(i=0;i<k;i++){
h-=c[i]; //依次减去最大的,得到所需最小工作量
if(h<=0) break;
}
cout<<i+1<<endl;
return 0;
}