中石油训练赛 - 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 will automatically start flowing into adjacent empty cells. From these cells, the honey will again flow to other neighbouring empty cells. 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?
?
輸入
? 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 ?lled 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 a single integer, the number of cells you have to funnel honey into directly to store all your honey in the hive.
?
樣例輸入
復制樣例數據
8 4 4 . # # .# . # . # # # .# . . .樣例輸出
3題目鏈接:點擊查看
題目大意:給出一個h表示現在身上的蜂蜜數量,再給出一個蜂巢的結構圖,黑色表示已經滿了,白色表示是空著的,每個小格子互相都是連通的,我們可以將身上的蜂蜜往小格子中填充,問若要將身上的蜂蜜都填充到蜂巢中,最少需要對幾個小格子操作
題目分析:emmmm,我知道我的語文很差,題意可能沒說清楚,不過轉換一下,這就是一個讓求最大連通塊的問題,只不過這個問題有兩個方面需要注意一下,第一就是我們需要將所有的連通塊都求出來,然后對每個連通塊進行降序排序,因為這個題目中的dfs是邊搜邊更新的,所以每個點至多遍歷一次,時間復雜度也就控制在了n*m之內,這樣就不用擔心遞歸會超時的問題了,第二個方面就是這個題目中,不像中規中矩的那種矩形一樣是上下左右走的,而是每個點有6個方向可以走,而奇數行和偶數行的方向又有那么一點點不同,所以我們一共設置12個方向,分別供奇數行和偶數行的點來使用,這個畫個圖就能推出來6個節點的編號,這里不贅述了
然后還有一個小坑,就是在輸入的時候,題目每個節點之間都有一個空格,十分的惡心人,而且偶數行的開頭還會有一個前置空格,我們在輸入的時候要記著用getchar讀掉,或者可以直接用cin,可以略過空格直接讀到符號,cin大法好嗷,還有一點,這個題目多組輸入會TLE,我人當時就傻了,可能還是我太菜了吧555
上代碼吧:
#include<iostream> #include<algorithm> using namespace std;const int N=1e3+100;char maze[N][N];int ans[N*N];int cnt;int h,n,m;const int b1[6][2]={0,1,0,-1,1,0,-1,0,-1,-1,1,-1};//jiconst int b2[6][2]={0,1,0,-1,1,0,-1,0,1,1,-1,1};//ouint num;void dfs(int x,int y) {num++;maze[x][y]='#';for(int k=0;k<6;k++){int xx,yy;if(x&1){xx=x+b2[k][0];yy=y+b2[k][1];}else{xx=x+b1[k][0];yy=y+b1[k][1];}if(xx<0||yy<0||xx>=n||yy>=m)continue;if(maze[xx][yy]=='#')continue;dfs(xx,yy);} }bool cmp(int a,int b) {return a>b; }int main() {scanf("%d%d%d",&h,&n,&m);cnt=0;getchar();for(int i=0;i<n;i++)for(int j=0;j<m;j++)cin>>maze[i][j];for(int i=0;i<n;i++)for(int j=0;j<m;j++){if(maze[i][j]=='.'){num=0;dfs(i,j);ans[cnt++]=num;}}sort(ans,ans+cnt,cmp); // for(int i=0;i<cnt;i++) // cout<<ans[i]<<' '; // cout<<endl;int temp=0;int tem=0;int t=0;while(tem<h&&t<cnt){temp++;tem+=ans[t++];}cout<<temp<<endl;return 0; }?
總結
以上是生活随笔為你收集整理的中石油训练赛 - Bee Problem(dfs+连通块)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中石油训练赛 - Isomorphic
- 下一篇: CodeForces - 1030C V