1. 程式人生 > >SJTUOJ 1003. 二哥養細菌

SJTUOJ 1003. 二哥養細菌

題目內容

題目描述
二哥不僅種蘋果和花生,還養了很多細菌。二哥的細菌培養皿成方格形,邊長為L。長期培養後,二哥發現了細菌繁殖的規律:最初每個格子裡的細菌及其後代都會獨立繁殖,每次繁殖都會在其上下左右四個相鄰的格子裡產生新的細菌,而已經存在的細菌在培養皿充滿細菌之前都不會死亡。另外,有一些格子裡可能還有抗生素,細菌在有抗生素的格子裡無法繁殖。

二哥於是發明了一個遊戲:取一個新的培養皿,在某些格子裡放入細菌或抗生素,然後觀察細菌不斷繁殖直至充滿整個培養皿的所有沒有抗生素的格子。不過二哥已經對這個遊戲厭煩了,他現在只想知道經過多少輪繁殖後,細菌會充滿整個培養皿(不算有抗生素的格子)。

輸入格式
第1行有1個整數,邊長L。

第2行至第L+1行,每行有L個整數,取值為0、1或2。0表示格子裡最初沒有細菌,1表示格子裡最初有細菌,2表示格子裡最初有抗生素。

輸出格式
輸出一個整數m,表示經過m輪繁殖後,細菌會充滿整個培養皿(不算有抗生素的格子)。

說明
【樣例解釋】 第一輪繁殖:

2 1 0
1 1 1
0 1 0

第二輪繁殖:

2 1 1
1 1 1
1 1 1

【資料範圍】

對於全部資料:1≤L≤1001≤L≤100 ,保證最終能夠充滿培養皿(不算有抗生素的格子)。

Sample Input
3
2 0 0
0 1 0
0 0 0
Sample Output
2

程式碼實現及分析

標準廣度優先搜尋,預估了一下佇列長度最大可能佔半個地圖(初始1,0相間隔),

#include <stdio.h>
#define LIM 5000
int main()
{
    int g[100][100],n,i,j,over,input;
    int queue[LIM] = {0};
    int qh = 0,qt = 0;
    
    while(scanf("%d",&n)!=EOF)
    {
        for(i = 0; i < n; i++){
            for(j=0;j<n;j++){
                scanf
("%d", &input); if(2 == input){ g[i][j] = -1; } else{ g[i][j]=input; } if(1==g[i][j]){ queue[qt++] = i*100+j; } } } while(1){ i = queue[qh]/100; j = queue[qh]%100; if(i > 0 && 0 == g[i-1][j]){ queue[qt] = (i-1)*100+j; g[i-1][j]=g[i][j]+1; qt++; if(qt > LIM){ qt = 0; } } if(j > 0 && 0 == g[i][j-1]){ queue[qt] = i*100+j-1; g[i][j-1]=g[i][j]+1; qt++; if(qt > LIM){ qt = 0; } } if(i < n-1 && 0 == g[i+1][j]){ queue[qt] = (i+1)*100+j; g[i+1][j]=g[i][j]+1; qt++; if(qt > LIM){ qt = 0; } } if(j < n-1 && 0 == g[i][j+1]){ queue[qt] = i*100+j+1; g[i][j+1]=g[i][j]+1; qt++; if(qt > LIM){ qt = 0; } } qh++; if(qh >= LIM){ qh = 0; } if(qh == qt){ break; } } over = (qh - 1 + LIM) % LIM; i = queue[over]/100; j = queue[over]%100; printf("%d\n",g[i][j]-1); } return 0; }

時間:26ms 空間:9452kb