中石油训练赛 - 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.
?
樣例輸入
復(fù)制樣例數(shù)據(jù)
8 4 4 . # # .# . # . # # # .# . . .樣例輸出
3題目鏈接:點(diǎn)擊查看
題目大意:給出一個(gè)h表示現(xiàn)在身上的蜂蜜數(shù)量,再給出一個(gè)蜂巢的結(jié)構(gòu)圖,黑色表示已經(jīng)滿了,白色表示是空著的,每個(gè)小格子互相都是連通的,我們可以將身上的蜂蜜往小格子中填充,問(wèn)若要將身上的蜂蜜都填充到蜂巢中,最少需要對(duì)幾個(gè)小格子操作
題目分析:emmmm,我知道我的語(yǔ)文很差,題意可能沒(méi)說(shuō)清楚,不過(guò)轉(zhuǎn)換一下,這就是一個(gè)讓求最大連通塊的問(wèn)題,只不過(guò)這個(gè)問(wèn)題有兩個(gè)方面需要注意一下,第一就是我們需要將所有的連通塊都求出來(lái),然后對(duì)每個(gè)連通塊進(jìn)行降序排序,因?yàn)檫@個(gè)題目中的dfs是邊搜邊更新的,所以每個(gè)點(diǎn)至多遍歷一次,時(shí)間復(fù)雜度也就控制在了n*m之內(nèi),這樣就不用擔(dān)心遞歸會(huì)超時(shí)的問(wèn)題了,第二個(gè)方面就是這個(gè)題目中,不像中規(guī)中矩的那種矩形一樣是上下左右走的,而是每個(gè)點(diǎn)有6個(gè)方向可以走,而奇數(shù)行和偶數(shù)行的方向又有那么一點(diǎn)點(diǎn)不同,所以我們一共設(shè)置12個(gè)方向,分別供奇數(shù)行和偶數(shù)行的點(diǎn)來(lái)使用,這個(gè)畫(huà)個(gè)圖就能推出來(lái)6個(gè)節(jié)點(diǎn)的編號(hào),這里不贅述了
然后還有一個(gè)小坑,就是在輸入的時(shí)候,題目每個(gè)節(jié)點(diǎn)之間都有一個(gè)空格,十分的惡心人,而且偶數(shù)行的開(kāi)頭還會(huì)有一個(gè)前置空格,我們?cè)谳斎氲臅r(shí)候要記著用getchar讀掉,或者可以直接用cin,可以略過(guò)空格直接讀到符號(hào),cin大法好嗷,還有一點(diǎn),這個(gè)題目多組輸入會(huì)TLE,我人當(dāng)時(shí)就傻了,可能還是我太菜了吧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; }?
總結(jié)
以上是生活随笔為你收集整理的中石油训练赛 - Bee Problem(dfs+连通块)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 中石油训练赛 - Isomorphic
- 下一篇: CodeForces - 1030C V