「人材獲得作戦・4 試験問題ほか」という記事で取り上げられている迷路の最短経路を求める問題をJavaで解いてみました。
ファイル入出力以外は、ほとんどCで書いても変わらないようなコードです。
一応、検索しないで1時間くらいでした。
ファイル入出力以外は、ほとんど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");
}
}
}











http://trwtnb.blogspot.com/2010/04/java.html
おつかれさまでした。私は以前、直接最短経路問題というわけではなかったのですが、似たような問題にぶちあたって自分で解決したことがあって、そのときの経験があったのでさくさくできましたが、全くのはじめてだとつらそうです。なんにせよ、プログラミングは経験というか引き出しが多いと後々役に立つことが多いみたいです。