問題概要
ある規則によって作成されるフラクタルが、与えられた平面上にいくつかるか数える。
方針
フラクタルかどうかは分割統治で判定できる。メモ化して高速化する。実装ややこしそうと思ったけど、以外と簡単に書けた。
ソースコード
using namespace std; #define REP(i,n) for(int i=0; i<(int)(n); i++) string bd[512]; bool dp[1<<4][10][512][512]; int r, c; int main() { cin >> r >> c; REP (i, r) cin >> bd[i]; // base case for (int i = 0; i + 1 < r; i++) { for (int j = 0; j + 1 < c; j++) { int mask = 0; mask |= (bd[i][j] == '*'); mask <<= 1; mask |= (bd[i][j+1] == '*'); mask <<= 1; mask |= (bd[i+1][j] == '*'); mask <<= 1; mask |= (bd[i+1][j+1] == '*'); dp[mask][1][i][j] = true; } } int size = 2; for (int k = 2; k < 10; k++) { size *= 2; for (int i = 0; i + size - 1 < r; i++) { for (int j = 0; j + size - 1 < c; j++) { for (int p = 0; p < 16; p++) { dp[p][k][i][j] = true; for (int q = 0; q < 4; q++) { int x = i; int y = j; if ((q & 1) == 0) y += size / 2; if (q / 2 == 0) x += size / 2; if (p & 1 << q) dp[p][k][i][j] &= dp[15][k-1][x][y]; else dp[p][k][i][j] &= dp[p][k-1][x][y]; } } } } } int ret = 0; for (int i = 0; i < 512; i++) for (int j = 0; j < 512; j++) for (int p = 0; p < 16; p++) for (int q = 2; q < 10; q++) ret += dp[p][q][i][j]; cout << ret << endl; return 0; }
0 件のコメント:
コメントを投稿