2010-11-14
第 9 回 JOI 予選 5 問題 (失敗編)
学校の帰り部、石川啄木の短歌 「こころよき 疲れなるかな 息もつかず 仕事をしたる 後のこの疲れ」 に歌われるような「心地よい疲労感」に包まれたある日の午後部のこと。
予選4の問題のときに再帰をお手の物にした気でいた僕は、 予選5の問題も同じ手(もろちん再帰)を思いついてしまった。 これが悪夢の始まりであったーー。
まずはそのソースコードをどうぞ。
#include <stdio.h>
#include <stdlib.h>
int *pw, *ph;
long long *pcount;
int routing(int x, int y, int compass){
// printf("%d %d¥n", x, y);
if(x == *pw && y == *ph){
/*到着した場合*/
// printf("GOAL!!¥n");
*pcount = *pcount + 1;
if(0 == *pcount % 10000000) printf("%lld¥n", *pcount);
return 0;
}else if((x == *pw && compass == -1) || (y == *ph && compass == -2)){
/*もうその方向へは進めない場合*/
// printf("COLLISION!!¥n");
return 0;
}
//getchar();
int temp;
if(x != *pw && compass != -2){
if(abs(compass) == 1 || abs(compass) == 0){temp = 1;}else{temp = -1;}
routing(x+1, y, temp); //**再帰っ!**
}
if(y != *ph && compass != -1){
if(abs(compass) == 2 || abs(compass) == 0){temp = 2;}else{temp = -2;}
routing(x, y+1, temp); //**再帰っ!**
}
return 0;
}
int main(){
int w, h, result;
long long count = 0;
scanf("%d %d", &w, &h);
pw = &w;
ph = &h;
pcount = &count;
getchar();
routing(1, 1, 0); //初期位置は(1, 1)におり、また右左折していない
result = count % 100000;
printf("¥nANS:%d¥n", result);
return 0;
}
別に動作がおかしい訳ではない。入出力例?ちゃんと通る。入力1?通るさ。 入力2や3もお手の物。
しかし…4,5に地雷が含まれていたのであった。
96 x 87 の道路の会社へ行くルートが幾通りもあることは想像はつくが、 コンピュータならすぐに処理をしてくれる―そう信じていた。 しかし、現実はそう甘くはなかった。
実行を始めて10秒―。 無反応。
実行を始めて1分―。 音沙汰無し。
実行を始めて1時間―。 うんともすんとも言わない。
このまま待ち続ければいずれは解答が得られるであろうが、 こんなプログラムでは本番に提出できないのは必至―。
ということで、解説を読みながら勉強中なのですが、全くわかりません。 誰か教えてください…。