O(N^6)の全通りでも間に合う。
O(N^4)
左上とある点を対角に持つ四角形の中にあるコインの数を、前もって数えておく。
class DropCoins {
public:
int getMinimum(vector <string> B, int K)
{
const int H = B.size();
const int W = B[0].size();
int sum[H + 1][W + 1];
fill(&sum[0][0], &sum[H][W + 1], 0);
for (int i = 0; i < H; ++i) {
for (int j = 0; j < W; ++j) {
for (int k = 0; k <= i; ++k) {
for (int l = 0; l <= j; ++l) {
sum[i + 1][j + 1] += B[k][l] != '.';
}
}
}
}
int mn = 1 << 30;
for (int i = 0; i < H; ++i) {
for (int j = 0; j < W; ++j) {
for (int k = i; k < H; ++k) {
for (int l = j; l < W; ++l) {
int c = 0;
c += sum[k + 1][l + 1];
c += sum[i][j];
c -= sum[i][l + 1];
c -= sum[k + 1][j];
if (c == K) {
int a = min(i, H - k - 1);
int b = min(j, W - l - 1);
mn = min(mn, i + j + H - k - 1 + W - l - 1 + a + b);
}
}
}
}
}
return mn == (1 << 30) ? -1 : mn;
}
};
本番で通したO(N^6)。全部試す。
class DropCoins {
public:
int getMinimum(vector <string> B, int K) {
const int H = B.size();
const int W = B[0].size();
char g[H][W];
for (int i = 0; i < H; ++i) {
for (int j = 0; j < W; ++j) {
g[i][j] = B[i][j];
}
}
const int inf = 1 << 30;
int mn = inf;
for (int i = 0; i < H; ++i) {
for (int j = 0; j < W; ++j) {
for (int k = i; k < H; ++k) {
for (int l = j; l < W; ++l) {
int cnt = 0;
for (int a = i; a <= k; ++a) {
for (int b = j; b <= l; ++b) {
if (g[a][b] == 'o') ++cnt;
}
}
cout << i << ' ' << j << " =>> " << k << ' ' << l << endl;
if (cnt == K) {
int cost = 0;
int U = i;
int L = j;
int D = H - 1 - k;
int R = W - 1 - l;
cout << U << ' ' << L << ' ' << D << ' ' << R << endl;
cost += min(U * 2 + D, D * 2 + U);
cost += min(R * 2 + L, L * 2 + R);
mn = min(mn, cost);
}
}
}
}
}
return mn == inf ? -1 : mn;
}
};
0 件のコメント :
コメントを投稿