Sim's blog

電子工作はじめてみました

最短迷路問題のJavaコード

2010-01-13 23:51:12 | その他
人材獲得作戦・4 試験問題ほか」という記事で取り上げられている迷路の最短経路を求める問題をJavaで解いてみました。
ファイル入出力以外は、ほとんどCで書いても変わらないようなコードです。
一応、検索しないで1時間くらいでした。
import java.io.File;
import java.util.Scanner;


public class Maze {

    public static void main(String[] args) throws Exception {
        new Maze().run();
    }

    final int MAXSIZE = 128 * 128;
    final int START = 0;
    final int WALL  = -1;
    final int BLANK = -2;
    final int GOAL  = -3;
    final int ROUTE = -4;

    final boolean AnswerType = true; // falseで全解出力

    int[] ban = new int[MAXSIZE];
    int[] answer = new int[MAXSIZE];
    int xsize;
    int ysize;
    int bansize;
    int startpos;
    int goalpos;

    void run() throws Exception{
        read("maze.txt");
        solve();
    }

    void read(String filename) throws Exception {
        Scanner scan = new Scanner(new File(filename));
        String s;
        int i, p;

        // 配列オーバーフローとかはチェックしない
        p = 0;
        for(ysize = 0; scan.hasNext(); ysize++){
            s = scan.nextLine();
            for(i = 0; i < s.length(); i++){
                switch(s.charAt(i)){
                case '*' : ban[p] = WALL;  break;
                case ' ' : ban[p] = BLANK; break;
                case 'S' : ban[p] = START; startpos = p; break;
                case 'G' : ban[p] = GOAL;  goalpos  = p; break;
                }
                p++;
            }
            xsize = i;
        }
        bansize = xsize * ysize;
    }

    void solve(){
        for(int i = 0; i < bansize; i++) answer[i] = ban[i];

        // mark
        int level = mark();

        // 戻り道を探す
        search(goalpos, level);
    }

    int mark(){
        int p;
        int level;
        for(level = 0; ; level++){
            for(p = 0; p < bansize; p++){
                if(ban[p] == level){
                    // 枠のチェックなし、というかここはキューに積む方がいい。
                    if(ban[p - 1] == BLANK) ban[p - 1] = level + 1;
                    if(ban[p + 1] == BLANK) ban[p + 1] = level + 1;
                    if(ban[p - xsize] == BLANK) ban[p - xsize] = level + 1;
                    if(ban[p + xsize] == BLANK) ban[p + xsize] = level + 1;
                    if(ban[p - 1] == GOAL || ban[p + 1] == GOAL || ban[p - xsize] == GOAL || ban[p + xsize] == GOAL){
                        return level;
                    }
                }
            }
        }
    }

    boolean check(int p, int level){
        if(ban[p] == level){
            answer[p] = ROUTE;
            if(search(p, level - 1)) return true;
            answer[p] = BLANK;
        }
        return false;
    }

    boolean search(int p, int level){
        if(level == 0){
            disp(answer);
            return AnswerType;
        }
        if(check(p - 1, level)) return true;
        if(check(p + 1, level)) return true;
        if(check(p - xsize, level)) return true;
        if(check(p + xsize, level)) return true;
        return false;
    }

    void disp(int[] ban){
        int x, y, p;
        p = 0;
        for(y = 0; y < ysize; y++){
            for(x = 0; x < xsize; x++){
                switch(ban[p]){
                case WALL  : System.out.printf("*"); break;
                case BLANK : System.out.printf(" "); break;
                case START : System.out.printf("S"); break;
                case GOAL  : System.out.printf("G"); break;
                default    : System.out.printf("$"); break;
                }
                p++;
            }
            System.out.printf("\n");
        }
    }
}


1月12日(火)のつぶやき

2010-01-13 00:50:37 | Twitter
04:39 from TwitPic


- 作りかけの基板と較べてみた。
05:58 from web
久しぶりにブログ書いた。「1つの抵抗をn個使って作れる抵抗値」http://bit.ly/7YfHx0
13:50 from web
円周率新記録のフランスの人のページ http://bellard.org/ それにしても、パソコンで新記録とはすごいかも
14:25 from web (Re: @Ohki
@Ohki 非正規品というのが流通してるらしいです。もしかして・・・。http://www.sii.co.jp/cp/n-dictionary/lineup/dbj990/
23:17 from Echofon (Re: @sonson1919
@sonson1919 無謀にもUSBプロトコルアナライザです。
23:19 from web
今から挑戦。RT @ hmori ああいう質題されたら最短という時点であきらめる私だな。 http://okajima.air-nifty.com/b/2010/01/post-abc6.html
23:36 from web
問題を読み込む所がやっとできた。
by Sim0000 on Twitter