有一批易感人群住在網格狀的宿舍區內,宿舍區為n*n的矩陣,每個格點為乙個房間,房間裡可能住人,也可能空著。在第一天,有些房間裡的人得了流感,以後每天,得流感的人會使其鄰居傳染上流感,(已經得病的不變),空房間不會傳染。請輸出第m天得流感的人數。
第一行乙個數字n,n不超過100,表示有n*n的宿舍房間。
接下來的n行,每行n個字元,』.』表示第一天該房間住著健康的人,』#』表示該房間空著,』@』表示第一天該房間住著得流感的人。
接下來的一行是乙個整數m,m不超過100。
輸出第m天,得流感的人數。
5....#
.#.@.
.#@..
#....
.....
4
16分析:首先思路應該很簡單,就是在指定的天數內模擬,把@旁邊不是#的格仔都改成@。抱著這樣輕視的心態,打出了第一版**:
#include#include#include
using
namespace
std;
char a[105][105
];int n,day,res=0
;int dx[4]=;
int dy[4]=;//
四個方向
intmain()
getchar();
}cin>>day;
for(int i=1;i//
天數內模擬 }}
}}
for(int i=1;i<=n;i++)
}cout
}
執行了一下,發現得到的結果格外大,比如上面那個例子,得出的結果竟然是二十多!
我又編寫了debug函式,輸出每一天的感染情況。我立即發現了問題。
由於程式從上到下,從左到右遍歷,只要看見『@』就執行傳染。問題是,這些'@'並不一定都是當天原來的感染者!也有可能是原來的感染者傳播後生成的!舉個例子:設n=3,初始陣列如下:
1 2 3
1 . @ .
2 . . .
3 . . .
設模擬了一天的情況,則應該變為:
1 2 3
1 @ @ @
2 . @ .
3 . . .
沒錯吧?可是接著迴圈,問題就來了。迴圈找到了點(2,2),發現這裡也有乙個感染者。於是接著往下「傳染」:
1 2 3
1 @ @ @
2 @ @ @
3 . @ .
看到(3,2)又發現乙個,於是繼續傳染:
1 2 3
1 @ @ @
2 @ @ @
3 @ @ @
很明顯,最後的結果是,一天之內,9個人全部被感染!然而真實情況是這樣嗎?正確的做法是,到第二個步驟(只有四個@)時就結束。迴圈混淆了當天原有的感染者和新感染者。但實際上只要考慮當天原有的感染者才對。新感染者到第二天才會成為「原有的感染者」。
於是,我改了一下。用乙個三維陣列k[i][m][c]表示第i天區域內第m個原有感染者的位置,c=0表示橫座標,c=1表示縱座標。掃瞄完成之後,陣列存放了原有感染者的位置,然後在根據這些位置進行「傳染」,這樣,就不會混淆原有感染者和新感染者了!
第二版ac**:
#include#include#include
using
namespace
std;
char a[105][105
];short
int k[105][10025][2],m=1
;int n,day,res=0
;int dx[4]=;
int dy[4]=;
intmain()
getchar();
}cin>>day;
for(int i=1;i)}}
for(int n=1;n<=m;n++)
}m=1;//
注意重置m,供下一天使用,因為m是指當天的感染者序數而不是全部的。
}
for(int i=1;i<=n;i++)
}cout
}
第二版
1191 流感傳染
時間限制 1000 ms 記憶體限制 65536 kb 提交數 4961 通過數 2667 有一批易感人群住在網格狀的宿舍區內,宿舍區為n n的矩陣,每個格點為乙個房間,房間裡可能住人,也可能空著。在第一天,有些房間裡的人得了流感,以後每天,得流感的人會使其鄰居傳染上流感,已經得病的不變 空房間不會...
1191 流感傳染
題目描述 有一批易感人群住在網格狀的宿舍區內,宿舍區為n n的矩陣,每個格點為乙個房間,房間裡可能住人,也可能空著。在第一天,有些房間裡的人得了流感,以後每天,得流感的人會使其鄰居傳染上流感,已經得病的不變 空房間不會傳染。請輸出第m天得流感的人數。輸入 第一行乙個數字n,n不超過100,表示有n ...
1191 流感傳染
此題做題思路 這個題考查模擬矩陣的搜尋過程。用字元二維陣列存放網格狀的宿舍區,用 int next 4 4 來模擬感染四個方向。於是大概5m後出現如下 includeusing namespace std char a 101 101 int n,m,cnt 0 int next 4 4 四個方向感...