Skip to content

Instantly share code, notes, and snippets.

@amoshyc
Last active August 29, 2015 14:16
Show Gist options
  • Save amoshyc/33c4c4bb57c35a189865 to your computer and use it in GitHub Desktop.
Save amoshyc/33c4c4bb57c35a189865 to your computer and use it in GitHub Desktop.
poj3009

Poj 2431

分析

從測資中可以發現,當 stone 撞上 block 後,block 會立即消失,stone 停在 block 的前一格。

因題目有限制搜尋深度,並且為了每次遞迴不記憶整個 board,所以使用 dfs + 剪枝。在每個轉折點依 上下左右 四個方向遞迴搜尋下去(注意,只有當該方向的第一格是空的時才可遞迴該方向),每次遇到 goal,更新 result 值。

AC Code

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdio>

using namespace std;

int data[20][20];
int W, H;
int result;

int goal_row;
int goal_col;

int source_row;
int source_col;

int delta_row[4] = {0, 0, +1, -1};
int delta_col[4] = {+1, -1, 0, 0};

bool is_inside(int row, int col) {
    return (0 <= row && row < H && 0 <= col && col < W);
}

void dfs(int row, int col, int depth) {
    // printf("(%d, %d, %d)\n", row, col, depth);

    if (depth > 10)
        return;

    if (depth > result)
        return;

    for (int dir = 0; dir < 4; dir++) {
        int new_row = row + delta_row[dir];
        int new_col = col + delta_col[dir];

        if (is_inside(new_row, new_col) == false || data[new_row][new_col] == 1)
            continue;

        while (is_inside(new_row, new_col) && data[new_row][new_col] == 0) {
            if (new_row == goal_row && new_col == goal_col) {
                result = min(result, depth+1);
                break;
            }

            new_row += delta_row[dir];
            new_col += delta_col[dir];
        }

        if (is_inside(new_row, new_col) == false) {
            continue;
        }
        else if (data[new_row][new_col] == 1) { // encounter blocks
            data[new_row][new_col] = 0;

            int stop_row = new_row - delta_row[dir];
            int stop_col = new_col - delta_col[dir];
            dfs(stop_row, stop_col, depth+1);

            data[new_row][new_col] = 1;
        }
    }
}

int main() {
    while (cin >> W >> H) {
        if (W == 0 && H == 0) break;

        memset(data, -1, sizeof(data));
        result = 11;

        for (int row = 0; row < H; row++) {
            for (int col = 0; col < W; col++) {
                cin >> data[row][col];

                if (data[row][col] == 2) {
                    source_row = row;
                    source_col = col;
                    data[row][col] = 0;
                }

                if (data[row][col] == 3) {
                    goal_row = row;
                    goal_col = col;
                    data[row][col] = 0;
                }
            }
        }

        dfs(source_row, source_col, 0);
        cout << ((result == 11) ? -1 : result) << "\n";
    }

    return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment