備忘録

まとめておきたいことのメモ 主にプロコンのこと

AOJ-ICPC 1166 その2

この前考えていた問題が通ったのでメモ。

#include <cstdio>
#include <iostream>
#include <cmath>
#include <ctype.h>
#include <string> 
#include <sstream>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <map>
#include <queue>
#include <utility>
#include <vector>
#include <set>
 
using namespace std;
 
// →にx軸、↓にy軸を取る
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
 
int meiro[40][40][40][40];
// meiro[a][b][c][d] ... (a, b)から(c, d)へ移るのに壁があれば1、なければ0
int tesu[40][40];
int issearched[40][40];
int w, h;
 
void tansaku(int a, int b);
 
int main()
{
    while(1){
        cin >> w >> h;
        if(w == 0 && h == 0) break;
        // 以下のfor文においてwとhが逆になっていたので訂正
        for(int i = 0; i < w; i++){
            for(int j = 0; j < h; j++){ 
                tesu[i][j] = 0;
                issearched[i][j] = 0;
            }
        }
        // 点aから点bへ移る場合は考えていたものの逆向きのこと(点bから点a)を無視していた。
        // 逆向きからも壁の有無も考える。
        for(int i = 0; i < h - 1; i++){
            for(int j = 0; j < w - 1; j++){
                cin >> meiro[j][i][j + 1][i];
                meiro[j + 1][i][j][i] = meiro[j][i][j + 1][i];
            }
            for(int j = 0; j < w; j++){
                cin >> meiro[j][i][j][i + 1];
                meiro[j][i + 1][j][i] = meiro[j][i][j][i + 1];
            }
        }
        for(int i = 0; i < w - 1; i++){
            cin >> meiro[i][h - 1][i + 1][h - 1];
            meiro[i + 1][h - 1][i][h - 1];
        }
        tansaku(0, 0);
        cout << tesu[w - 1][h - 1] << endl;
    }
    return 0;
}
 
void tansaku(int a, int b)
{
    queue<pair<int, int> > qu;
    qu.push(pair<int, int>(a, b));
    tesu[a][b] = 1;
    issearched[a][b] = 1;
    int x, y, next_x, next_y;
    while(1){
        if(qu.empty()) break;
        x = (qu.front()).first;
        y = (qu.front()).second;
        for(int i = 0; i < 4; i++){
            next_x = x + dx[i];
            next_y = y + dy[i];
            if(next_x < 0 || next_x >= w || next_y < 0 || next_y >= h) continue;
            if(issearched[next_x][next_y] == 0 && meiro[x][y][next_x][next_y] == 0){
                issearched[next_x][next_y] = 1;
                tesu[next_x][next_y] = tesu[x][y] + 1;
                qu.push(pair<int, int>(next_x, next_y));
            }
        }
        qu.pop();
    }
    return;
}

通らなかった理由は以下の二つ。

  • l35: 初期化でwとhが逆になっていた
  • l47, 51, 56: 反対向きに進む場合の壁の有無を考えるのを忘れていた


とりあえず友人に聞いたところ「wとhが逆で違和感がある」とのこと。
自分でもどういう方向にx軸y軸とったかよくわからなくなるのでこの辺は問題をこなして慣れるべきだろうなーと思った。

【追記】ソースコードを色つきでのせられた。C++用のはないのね、Cしかないのね。
参考:
はてなブログにソースコードを色付けして貼り付ける方法 - sonickun.log
ソースコードを色付けして記述する(シンタックス・ハイライト) - はてなダイアリーのヘルプ