1細胞自動機(30分)
題目內容:
這是細胞自動機的非圖形版本。細胞自動機是指在一個二維網格內,每一個網格是一個細胞。每個細胞有活和死兩種狀態。
初始時刻,有些細胞是活的,有些細胞是死的。自動機的每一步,根據每個細胞周圍8個格子內的其他細胞的生存情況決定這個細胞下一步是否存活。具體的規則如下:
如果該細胞現在是活的,並且周圍8個格子中有2或3個活着的細胞,則繼續存活;如果周圍8個格子中的活着的細胞數量少於2個或多於3個,則死亡;
如果該細胞現在是死的,並且周圍8個格子中正好有3個活着的細胞,則細胞復活。
位於整個網格邊緣和頂角的細胞,它的周圍細胞可能少於8個。即越過網格的邊界不再有細胞。
每個細胞的生死變化,都不會影響當前這一步周圍的細胞,只會在下一步表現出來。
提示:課程中的代碼與上一句描述不同。
輸入格式:
首先輸入兩個正整數,範圍爲[3,102],依次表示網格的寬度和高度。
然後輸入多組正整數,依次表示一個活着的細胞的網格位置,每組數字中,第一個表示行號,第二個表示列號,均從0開始編號。
最後,以“-1 -1”表示不再有活着的細胞。-1 -1不是有效的位置。
然後,以一個正整數,範圍爲[1,10000],表示要求細胞自動機執行的步數。
輸出格式:
輸出一個正整數,表示執行完畢後,剩下的活着的細胞的數量。
輸入樣例:
3 3
1 1 1 2 0 1 2 1
-1 -1
1
輸出樣例:
7
代碼實現:
package high_project;
import java.util.Scanner;
public class endExam {
private int times;
private int width;
private int height;
int old_field[][];
int new_field[][];
Scanner in = new Scanner(System.in);
void Init() {
width = in.nextInt();
height = in.nextInt();
old_field = new int[height + 2][width + 2];
new_field = new int[height + 2][width + 2];
// 初始化爲0
for (int i = 0; i < height + 2; i++)
for (int j = 0; j < width + 2; j++) {
old_field[i][j] = 0;
old_field[i][j] = 0;
}
// 讀入活的細胞的位置
while (true) {
int i = in.nextInt();
int j = in.nextInt();
if (i == -1 && j == -1)
break;
old_field[i + 1][j + 1] = 1;
new_field[i + 1][j + 1] = 1;
}
// 讀入執行步數
times = in.nextInt();
}
void run() {
for (int k = 0; k < times; k++) {
for (int i = 1; i < height + 1; i++) {
for (int j = 1; j < width + 1; j++) {
int count = getNeighbor(i, j);
if (old_field[i][j] == 0) {
if (count == 3)// 細胞復活
new_field[i][j] = 1;
} else {
if (!(count == 2 || count == 3))// 細胞死亡
new_field[i][j] = 0;
}
}
}
// copy
for (int i = 1; i < height + 1; i++) {
for (int j = 0; j < width + 1; j++) {
old_field[i][j] = new_field[i][j];
}
}
}
}
int getNeighbor(int i, int j) {
// 計算位置爲i,j的細胞周圍活的細胞的數量
int temp = 0;
temp += old_field[i - 1][j] + old_field[i + 1][j] + old_field[i][j - 1] + old_field[i][j + 1];
temp += old_field[i - 1][j - 1] + old_field[i - 1][j + 1] + old_field[i + 1][j - 1] + old_field[i + 1][j + 1];
return temp;
}
int Count() {
// 計算活着的細胞的數量
int count = 0;
for (int i = 1; i < height + 1; i++) {
for (int j = 1; j < width + 1; j++) {
if (old_field[i][j] == 1)
count++;
}
}
return count;
}
void Test() {
Init();
run();
System.out.println(Count());
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new endExam().Test();
}
}