AOJ : 0230 - Ninja Climbing (忍者のビル登り)
問題概要
http://rose.u-aizu.ac.jp/onlinejudge/ProblemSet/description.jsp?id=0230&lang=jp
日本語の問題文なので説明省略です.
アルゴリズム
状態として, [左右のビルどちらにいるか, ビルの何階にいるか, 何回ジャンプしたか] を持たせて, 左右のビルの1階から幅優先させて解きました.
プログラム
#include <iostream> #include <queue> #include <cstring> using namespace std; #define REP(i,n,m) for(int i=n;i<m;i++) #define rep(i,n) REP(i,0,n) class P{ public: int b,h,cost; //ビルのどっちにいるか,ビルの階数,ジャンプ回数 P(int _b,int _h,int _cost){ b = _b; h = _h; cost = _cost; } }; int n; int b[2][101]; bool closed[2][101]; int solve(void){ queue<P> q; memset(closed,0,sizeof(closed)); q.push(P(0,0,0)); q.push(P(1,0,0)); while(!q.empty()){ P p = q.front(); q.pop(); if(b[p.b][p.h] == 1){ //はしご while(p.h<n && b[p.b][p.h]==1) p.h++; p.h--; } else if(b[p.b][p.h] == 2){ //すべる壁 while(b[p.b][p.h]==2) p.h--; } if(closed[p.b][p.h]) continue; closed[p.b][p.h] = true; if(p.h == n-1) return p.cost; rep(i,3) if(n > p.h + i) { q.push(P(!p.b,p.h+i,p.cost+1)); } } return -1; } int main(void){ while(cin>>n,n){ rep(i,2) rep(j,n) cin>>b[i][j]; int cal = solve(); if(cal == -1) cout<<"NA\n"; else cout<<cal<<endl; } return 0; }