C++_細菌の繁殖と拡散問題解
26635 ワード
タイトルの説明
辺長9の正方形培養皿では,正中心位置にm個の細菌が存在した.細菌の寿命は1日しかないが、毎日10個の子孫を繁殖させることができ、この10個の子孫は、元のセルに2個分布し、残りは周囲に隣接する8個のセルに均一に分布していると仮定する.n日後、培養皿中の細菌の分布状況を求めた.
入力フォーマット
2つの整数を入力し、1番目の整数mは中心位置細菌の個数(2≦m≦30)を表し、2番目の整数nは経過日数(1≦n≦4)を表す.
出力フォーマット
9行9列の整数行列を出力し、各行の整数間をスペースで区切ります.マトリックス全体は、n日後の培養皿上の細菌の分布を表す.
入力サンプル
出力サンプル
次は2の解法を提供します.大同小異ですが、どれだけ違いますか.
解法1
この方法は、毎日の状況を3次元配列に存在させ、k日目のx行y列を存在させることです.
プログラムは毎日のデータを保存するので、空間の複雑さが高く、日数が多くなると爆発します.
解法2
この方法は車輪のような方法で,b配列で計算し,b中のデータをaにコピーする.多層ループネストがあるので時間の複雑さが高くTLE(無理AC)しやすい
二つの方法にはそれぞれ取捨選択があり,皆さんの参考に供する.
小結
この問題は個人的にはあまり難しくないと思いますが、ACを何度も書いたので、境界条件がはっきりしていないものもありますので、気をつけてください.
PS:第二編題解
辺長9の正方形培養皿では,正中心位置にm個の細菌が存在した.細菌の寿命は1日しかないが、毎日10個の子孫を繁殖させることができ、この10個の子孫は、元のセルに2個分布し、残りは周囲に隣接する8個のセルに均一に分布していると仮定する.n日後、培養皿中の細菌の分布状況を求めた.
入力フォーマット
2つの整数を入力し、1番目の整数mは中心位置細菌の個数(2≦m≦30)を表し、2番目の整数nは経過日数(1≦n≦4)を表す.
出力フォーマット
9行9列の整数行列を出力し、各行の整数間をスペースで区切ります.マトリックス全体は、n日後の培養皿上の細菌の分布を表す.
入力サンプル
2 1
出力サンプル
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 2 2 2 0 0 0
0 0 0 2 4 2 0 0 0
0 0 0 2 2 2 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
次は2の解法を提供します.大同小異ですが、どれだけ違いますか.
解法1
#include
#include
using namespace std;
int be,day; //be
int a[5][10][10]; //3 ,
int main(){
int i,j,k;
cin>>be>>day;
a[0][4][4]=be; // , be
for(k=0;k<day;k++){
for(i=1;i<8;i++){
for(j=1;j<8;j++){
int tmp=a[k][i][j];
//
a[k+1][i][j]+=tmp*2; //
a[k+1][i-1][j]+=tmp; //
a[k+1][i-1][j-1]+=tmp; //
a[k+1][i-1][j+1]+=tmp; //
a[k+1][i][j-1]+=tmp; //
a[k+1][i][j+1]+=tmp; //
a[k+1][i+1][j]+=tmp; //
a[k+1][i+1][j-1]+=tmp; //
a[k+1][i+1][j+1]+=tmp; //
}
}
}
//
for(i=0;i<9;i++){
for(j=0;j<9;j++)
cout<<a[day][i][j]<<" ";
cout<<endl;
}
return 0;
}
この方法は、毎日の状況を3次元配列に存在させ、k日目のx行y列を存在させることです.
a[k][x][y]
プログラムは毎日のデータを保存するので、空間の複雑さが高く、日数が多くなると爆発します.
解法2
#include
#include
using namespace std;
int be,day;
int a[10][10],b[10][10];
void b0(){ // b
int i,j;
for(i=0;i<9;i++)
for(j=0;j<9;j++)
b[i][j]=0;
return;
}
int main(){
int i,j,k;
cin>>be>>day;
a[4][4]=be; //
for(k=0;k<day;k++){
for(i=1;i<8;i++){
for(j=1;j<8;j++){
// ,
int tmp=a[i][j];
b[i][j]+=tmp*2;
b[i-1][j]+=tmp;
b[i-1][j-1]+=tmp;
b[i-1][j+1]+=tmp;
b[i][j-1]+=tmp;
b[i][j+1]+=tmp;
b[i+1][j]+=tmp;
b[i+1][j-1]+=tmp;
b[i+1][j+1]+=tmp;
}
}
for(i=0;i<9;i++){
for(j=0;j<9;j++){
a[i][j]=b[i][j]; // a b
}
}
b0(); //
}
for(i=0;i<9;i++){ //
for(j=0;j<9;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
return 0;
}
この方法は車輪のような方法で,b配列で計算し,b中のデータをaにコピーする.多層ループネストがあるので時間の複雑さが高くTLE(無理AC)しやすい
二つの方法にはそれぞれ取捨選択があり,皆さんの参考に供する.
小結
この問題は個人的にはあまり難しくないと思いますが、ACを何度も書いたので、境界条件がはっきりしていないものもありますので、気をつけてください.
PS:第二編題解