Problem:
忍者のビル登り
忍者のあつしさんは、毎日朝早くから夜遅くまで忍者ビルの屋上から町を警備しています。この忍者ビルは、隣接する 2 つの同じ階数のビルであり、あつしさんは警備のために、ビルとビルの間をジャンプしながら屋上へ向かうことを日課としています。
この 2 つのビルは頻繁に清掃が行われるため、ビル登りの助けとなるはしごや障害となる滑りやすい部分があります。  しかも、はしごや滑りやすい部分の位置は毎日変わります。   そのためあつしさんは、屋上へ向かう方法を毎日考えなければいけません。
あつしさんは二つ並んだ同じ階数のビルの壁を跳び移りながら、ビルの屋上を目指します。ジャンプ
はどちらか一方のビルの1階から始められます。向かい側のビルへジャンプするときには、同じ階・1つ上の階・2 つ上の階の、いずれかに飛び移ることができます。
壁には以下の 3 種類があり、それぞれの壁にジャンプした後の移動が決まっています。
0. 普通の壁: 上下の移動はしない。次のジャンプはそこから行う。
1. はしご: はしごは 2 つ以上の階にまたがってかかっており、今いるはしごの一番上まで移動する。次のジャンプはそこから行う。
2. すべる壁: 普通の壁かはしごの一番上まで滑り落ちる。次のジャンプはそこから行う。
また、壁は 1 階から屋上のすぐ下の最上階まであり、屋上へはそのビルの最上階からのみ行くことが
できます。また、ビルの最下階の壁はすべる壁にはなりません。
2 つのビルの階数
n
と 2 つのビルの壁の種類を入力とし、最少で何回目のジャンプで最上階までたどり着き、屋上まで行くことができるかを出力するプログラムを作成してください。なお、どちらのビルの屋上にたどり着いてもよいものとします。ただし、あつしさんがどちらのビルの屋上へもたどり着けない場合は“NA”と出力してください。
Input
複数のデータセットの並びが入力として与えられます。入力の終わりはゼロひとつの行で示されます。
各データセットは以下の形式で与えられます。
n
a
1
a
2
...
a
n
b
1
b
2
...
b
n
１行目にビルの階数
n
(3 ≤
n
≤ 100) が与えられます。２行目に１ つ目のビルの 1 階から
n
階までの壁の情報
a
i
、３行目に２つ目のビルの 1 階から
n
階までの壁の情報
b
i
が与えられます。
a
i
, b
i
は
i
階目の壁の情報を表し、0 が普通の壁、1 がはしご(
i
階と
i
+1 階にまたがる)、2 がすべる壁を表します。
データセットの数は 60 を超えません。
Output
入力データセットごとに、ジャンプの回数を１行に出力します。
Sample Input
8
0 0 0 2 2 2 0 0
1 1 1 1 0 0 0 0
4
1 1 2 2
0 0 2 2
0
Output for the Sample Input
4
NA

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
int a[101],b[101],d[201][201],n;
main(){
	while(cin>>n,n){
		r(i,201)r(j,201)d[i][j]=1e8;
		r(i,n)cin>>a[i];
		r(i,n)cin>>b[i];
		r(i,n){
			if(a[i]==1){
				if(i>0&&a[i-1]==1)d[i][i-1]=0;
				if(i+1<n&&a[i+1]==1)d[i][i+1]=0;
			}
			if(a[i]==2){
				d[i][i-1]=0;
			}
			else{
				int j=i;
				if(j+2<n)d[i][j+100+2]=1;
				if(j+1<n)d[i][j+100+1]=1;
				d[i][j+100]=1;
			}
		}
		r(i,n){
			if(b[i]==1){
				if(i>0&&b[i-1]==1)d[i+100][i+100-1]=0;
				if(i+1<n&&b[i+1]==1)d[i+100][i+100+1]=0;
			}
			if(b[i]==2){
				d[i+100][i+100-1]=0;
			}
			else{
				int j=i;
				if(j+2<n)d[i+100][j+2]=1;
				if(j+1<n)d[i+100][j+1]=1;
				d[i+100][j]=1;
			}
		}
		r(k,201)r(i,201)r(j,201)d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
		int ans1=1e8,ans2=1e8,ans;
		if(b[n-1]!=2)ans1=min(d[0][n+100-1],d[100][n+100-1]);
		if(a[n-1]!=2)ans2=min(d[0][n-1],d[100][n-1]);
		ans=min(ans1,ans2);
		if(ans==1e8)cout<<"NA"<<endl;
		else cout<<ans<<endl;
	}
}
accuracy: 1
time_ms: 340
memory_kb: 3256
final_rank: 8

code_snippet: #include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
	
	while(true){
		int N;
		int Num[200];
		scanf("%d",&N);
		if(N==0)break;
		for(int i=0;i<2*N;i++)scanf("%d",&Num[i]);
		bool G[200][200];
		for(int i=0;i<2*N;i++){
			for(int j=0;j<2*N;j++){
				G[i][j]=false;
			}
		}
		for(int i=0;i<N;i++){
			if(Num[i]==0){
				for(int k=i+N;k<i+N+3&&k<2*N;k++){
					if(Num[k]==1){
						int j=k;
						while(j<2*N&&Num[j]==1){
							j++;
						}
						G[i][j-1]=true;
					}
					else if(Num[k]==2){
						int j=k;
						while(j>=N+1&&Num[j]==2){
							j--;
						}
						G[i][j]=true;
					}
					else{
						G[i][k]=true;
					}
				}
			}
			else if(Num[i]==1){
				int l=i;
				while(l<N&&Num[l]==1){
					l++;
				}
				l--;
				for(int k=l+N;k<l+N+3&&k<2*N;k++){
					if(Num[k]==1){
						int j=k;
						while(j<2*N&&Num[j]==1){
							j++;
						}
						G[i][j-1]=true;
					}
					else if(Num[k]==2){
						int j=k;
						while(j>=N+1&&Num[j]==2){
							j--;
						}
						G[i][j]=true;
					}
					else{
						G[i][k]=true;
					}
				}
			}
			else{
				int l=i;
				while(l>=1&&Num[l]==2)l--;
				for(int k=l+N;k<l+N+3&&k<2*N;k++){
					if(Num[k]==1){
						int j=k;
						while(j<2*N&&Num[j]==1){
							j++;
						}
						G[i][j-1]=true;
					}
					else if(Num[k]==2){
						int j=k;
						while(j>=N+1&&Num[j]==2){
							j--;
						}
						G[i][j]=true;
					}
					else{
						G[i][k]=true;
					}
				}
			}
		}
		for(int i=N;i<2*N;i++){
			if(Num[i]==0){
				for(int k=i-N;k<i-N+3&&k<N;k++){
					if(Num[k]==1){
						int j=k;
						while(j<N&&Num[j]==1){
							j++;
						}
						G[i][j-1]=true;
					}
					else if(Num[k]==2){
						int j=k;
						while(j>=1&&Num[j]==2){
							j--;
						}
						G[i][j]=true;
					}
					else{
						G[i][k]=true;
					}
				}
			}
			else if(Num[i]==1){
				int l=i;
				while(l<2*N&&Num[l]==1){
					l++;
				}
				l--;
				for(int k=l-N;k<l-N+3&&k<N;k++){
					if(Num[k]==1){
						int j=k;
						while(j<N&&Num[j]==1){
							j++;
						}
						G[i][j-1]=true;
					}
					else if(Num[k]==2){
						int j=k;
						while(j>=1&&Num[j]==2){
							j--;
						}
						G[i][j]=true;
					}
					else{
						G[i][k]=true;
					}
				}
			}
			else{
				int l=i;
				while(l>=N+1&&Num[l]==2)l--;
				for(int k=l-N;k<l-N+3&&k<N;k++){
					if(Num[k]==1){
						int j=k;
						while(j<N&&Num[j]==1){
							j++;
						}
						G[i][j-1]=true;
					}
					else if(Num[k]==2){
						int j=k;
						while(j>=1&&Num[j]==2){
							j--;
						}
						G[i][j]=true;
					}
					else{
						G[i][k]=true;
					}
				}
			}
		}
		int SS[200];
		for(int i=0;i<200;i++)SS[i]=1000;
		SS[0]=0;SS[N]=0;
		if(Num[0]==1){
			int I=0;
			while(Num[I]==1&&I<N){
				SS[I]=0;
				I++;
			}
			SS[I]=1000;
		}
		if(Num[N]==1){
			int I=N;
			while(Num[I]==1&&I<2*N){
				SS[I]=0;
				I++;
			}
			
			SS[I]=1000;
		}
		for(int k=0;k<2*N;k++){
			for(int i=0;i<2*N;i++){
				for(int j=0;j<2*N;j++){
					if(G[j][i]){
						SS[i]=min(SS[i],SS[j]+1);
					}
				}
			}
		}
		
		int ans=min(SS[N-1],SS[2*N-1]);
		if(ans==1000)printf("NA\n");
		else printf("%d\n",ans);
	}
	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 1240
final_rank: 5

code_snippet: #include <iostream>
#include <algorithm>
using namespace std;

int main() {
	int n;
	while(cin >> n, n) {
		int bill[2][128] = {0};
		int edge[256][256];
		const int INF = 512;
		for(int i = 0; i < 256; i++) {
			for(int j = 0; j < 256; j++) {
				edge[i][j] = INF;
			}
			edge[i][i] = 0;
		}

		for(int i = 0; i < 2; i++)
			for(int j = 0; j < n; j++)
				cin >> bill[i][j];

		for(int i = 0; i < 2; i++) {
			for(int j = 0; j < n; j++) {
				for(int k = 0; k < 3; k++) {
					if(j + k < n && (bill[i][j] == 0 || (bill[i][j] == 1 && bill[i][j+1] != 1))) {
						edge[n*i + j][n*(!i) + j + k] = 1;
					}
				}
			}
		}
		for(int i = 0; i < 2; i++) {
			for(int j = 1; j < n; j++) {
				if(bill[i][j-1] == 1 && bill[i][j] == 1)
					edge[n*i + j-1][n*i + j] = 0;
				else if(bill[i][j] == 2)
					edge[n*i + j][n*i + j-1] = 0;
			}
		}

		for(int i = 0; i < 2 * n; i++) {
			for(int j = 0; j < 2 * n; j++) {
				for(int k = 0; k < 2 * n; k++) {
					edge[j][k] = min(edge[j][k], edge[j][i] + edge[i][k]);
				}
			}
		}
		
		int res = INF;
		if(bill[0][n-1] != 2) {
			res = min(res, min(edge[0][n-1], edge[n][n-1]));
		}
		if(bill[1][n-1] != 2) {
			res = min(res, min(edge[0][2*n-1], edge[n][2*n-1]));
		}

		if(res == INF)
			cout << "NA" << endl;
		else
			cout << res << endl;
	}
}
accuracy: 1
time_ms: 110
memory_kb: 1416
final_rank: 6

code_snippet: #include <iostream>
#include <string>
#include <vector>
#include <cstring>
#include <climits>
#include <algorithm>
#include <map>
using namespace std;

const int INF = 1e7;
struct Edge { int from, to, cost; };

int main() {
    int n;
    while (cin >> n, n) {
        vector<int> a(2*n);
        for (int i=0; i<2*n; ++i) cin >> a[i];

        vector<Edge> edges;
        for (int i=0; i<2*n; ++i) {
            if (a[i] == 0 || (a[i] == 1 && (i%n == n-1 || a[i+1] != 1))) {
                edges.push_back((Edge){i, (i+n)%(2*n), 1});
                if (i%n == n-1) continue;
                edges.push_back((Edge){i, (i+n)%(2*n)+1, 1});
                if (i%n == n-2) continue;
                edges.push_back((Edge){i, (i+n)%(2*n)+2, 1});
            } else if (a[i] == 1) {
                edges.push_back((Edge){i, i+1, 0});
            } else if (a[i] == 2) {
                edges.push_back((Edge){i, i-1, 0});
            }
        }

        int d[200];
        fill(d, d+200, INF);
        d[0] = d[n] = 0;
        for (int k=0; k<600; ++k) {
            for (int i=0; i<(int)edges.size(); ++i) {
                d[edges[i].to] = min(d[edges[i].to], d[edges[i].from] + edges[i].cost);
            }
        }

        int ans = INF;
        if (a[n-1] != 2) ans = min(ans, d[n-1]);
        if (a[2*n-1] != 2) ans = min(ans, d[2*n-1]);
        if (ans == INF) {
            cout << "NA" << endl;
        } else {
            cout << ans << endl;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 1232
final_rank: 2

code_snippet: #include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <set>
#include <cstring>

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,j) FOR(i,0,j)
#define mp std::make_pair

typedef long long ll;
typedef unsigned long long ull;
typedef std::pair<int,int> P;
typedef std::pair<int,P> State;

const int INF = 1001001001;

// S N E W(南北東西)
const int dx[8] = {0, 0, 1, -1, 1, 1, -1, -1}, dy[8] = {1, -1, 0, 0, 1, -1, 1, -1};

int N;
int bills[2][100];
bool used[2][100][1000];

int rec(int bill, int floor, int t){
    if(floor == N-1 && bills[bill][floor] != 2){return t;}
    if(t >= 1000){return INF;}
    if(used[bill][floor][t]){return INF;}

    used[bill][floor][t] = true;

    int res = INF;
    if(bills[bill][floor] == 0){
        res = std::min(rec(!bill, floor, t+1), rec(!bill, floor+1, t+1));
        if(floor+2 < N){res = std::min(res, rec(!bill, floor+2, t+1));}
    }else if(bills[bill][floor] == 1){
        int nextFloor = floor;
        while(true){
            if(nextFloor + 1 == N || bills[bill][nextFloor+1] != 1){
                break;
            }else{
                nextFloor += 1;
            }
        }

        if(nextFloor == N-1){return t;}
        res = rec(!bill, nextFloor, t+1);
        res = std::min(res, rec(!bill, nextFloor+1, t+1));
        if(nextFloor+2 < N){res = std::min(res, rec(!bill, nextFloor+2, t+1));}
    }else{
        int nextFloor = floor;
        while(bills[bill][nextFloor] == 2){
            nextFloor -= 1;
        }

        // if(nextFloor+1 < N && !bill == 1 && nextFloor+1 == 4){printf("%d, %d, %d\n", bill, floor, t);}
        res = rec(!bill, nextFloor, t+1);
        if(nextFloor+1 < N){res = std::min(res, rec(!bill, nextFloor+1, t+1));}
        if(nextFloor+2 < N){res = std::min(res, rec(!bill, nextFloor+2, t+1));}
    }
    return res;
}

int main(){
    while(std::cin >> N, N){
        REP(i, 2){
            REP(j, N){
                std::cin >> bills[i][j];
            }
        }

        memset(used, 0, sizeof(used));
        int res = rec(1, 0, 0);
        memset(used, 0, sizeof(used));
        res = std::min(res, rec(0, 0, 0));

        if(res != INF){
            std::cout << res << std::endl;
        }else{
            std::cout << "NA" << std::endl;
        }
    }
}
accuracy: 1
time_ms: 60
memory_kb: 1408
final_rank: 4

code_snippet: #include <iostream>
#include <cstring>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#define fr first
#define sc second
#define INF (2 << 28)
using namespace std;

typedef pair<int, bool> iP;
typedef pair<int, iP> iiP;

int n, b[2][101];
int used[2][101][201];

int Dijkstra(){
  
  fill_n(**used, 2 * 101 * 201, INF);
  priority_queue<iiP, vector<iiP>, greater<iiP> > que;
  used[0][0][0] = 0, used[1][0][0] = 0;
  que.push(iiP(0, iP(0, false))), que.push(iiP(0, iP(0, true)));
  while(!que.empty()){
    iiP p = que.top(); que.pop();
    int cnt = p.fr, y = p.sc.fr;
    bool judge = p.sc.sc;
    
    //cout << p.sc.sc << " " << p.sc.fr << " " << p.fr << endl;
    if(p.sc.fr == n-1 && b[judge][y] != 2) return cnt;

    int c = 0;
    if(b[judge][y] == 1){
      while(b[judge][y + c] == 1 && y + c < n) c++;
      c--;
      if(y + c == n-1) return cnt;
    }
    else if(b[judge][y] == 2){
      while(b[judge][y + c] == 2) c--;
    }
    for(int i = 0; i < 3; i++){
      if(y + c + i < n && cnt + 1 < used[!judge][y + c + i][cnt + 1]){
	que.push(iiP(cnt + 1, iP(y + c + i, !judge)));
	used[!judge][y + c + i][cnt + 1] = cnt + 1;
      }
    }
  }
  return INF;

}    

int main(){
  
  while(cin >> n, n){
    for(int j = 0; j < 2; j++){
      for(int i = 0; i < n; i++) cin >> b[j][i];
    }
    
    int d = Dijkstra();
    if(d == INF) cout << "NA" << endl;
    else cout << d << endl;
  }

}
accuracy: 1
time_ms: 10
memory_kb: 1364
final_rank: 3

code_snippet: #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <cassert>
#include <iostream>
#include <cctype>
#include <sstream>
#include <string>
#include <list>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <utility>
#include <numeric>
#include <algorithm>
#include <iterator>
#include <bitset>
#include <complex>
#include <fstream>
#include <iomanip>
using namespace std;
typedef long long ll;
const double EPS = 1e-9;
typedef vector<int> vint;
typedef pair<int, int> pint;
#define rep(i, n) REP(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define MSG(a) cout << (#a) << " " << (a) << endl;
#define REP(i, x, n) for(int i = x; i < n; i++)
template<class T, class C> void chmax(T& a, C b){ if(a < b) a = b; }
template<class T, class C> void chmin(T& a, C b){ if(b < a) a = b; }
template<class T, class C> pair<T, C> mp(T a, C b){ return make_pair(a, b); }

const int INF = (1 << 30) / 2;

int main()
{
	int n;

	while(cin >> n && n)
	{
		vector<vint> v(2, vint(n));
		vector<vint> d((n + 1) * 2, vint((n + 1) * 2, INF));

		rep(i, 2) rep(j, n)
			cin >> v[i][j];


		rep(i, (n + 1))
			d[i][i] = 0;

		// ツつサツづェツつシツづェツづ個湘ェツ渉環つゥツづァ1ツ偲ィツづ督楪達ツづつォツづゥツづつアツづォツづ可陛督づーツ陳」ツづゥ
		rep(y, n) rep(x, 2)
		{
			if(v[x][y] != 2)
			{
				for(int c = 0; c < 3 && y + c < n; c++)
				{
					int ny = y + c, nx = (x + 1) % 2;
					d[y * 2 + x][ny * 2 + nx] = 1;
				}

				if(v[x][y] == 1)
				{
					if(y + 1 < n && v[x][y + 1] == 1)
						d[y * 2 + x][(y + 1) * 2 + x] = 0;
				}
			}
			else
			{
				if(0 <= y - 1 && v[x][y - 1] == 2)
					d[y * 2 + x][(y - 1) * 2 + x] = 0;
			}
		}

		// ツ催終ツマツスツつゥツづァツ陛督づーツ陳」ツづゥ
		if(v[0][n - 1] != 2) d[(n - 1) * 2][n * 2 + 1] = 0;
		if(v[1][n - 1] != 2) d[(n - 1) * 2 + 1][n * 2] = 0;


		
		// ツδ渉ーツシツδδδ仰フツδ債イツドツづ催短ツ仰猟猟」ツづーツ出ツつキ
		rep(k, 2 * (n + 1)) rep(i, 2 * (n + 1)) rep(j, 2 * (n + 1))
				chmin(d[i][j], d[i][k] + d[k][j]);


		// ツづつソツづァツつゥツづァツづつソツづァツづ可行ツつュツづ個つェツ暗ェツ氾板短ツつ「ツつゥ
		int res = min(min(d[0][2 * n], d[0][2 * n + 1]), min(d[1][2 * n], d[1][2 * n + 1]));


		if(res == INF)
			cout << "NA" << endl;
		else
			cout << res << endl;
	}
}
accuracy: 1
time_ms: 300
memory_kb: 0
final_rank: 7

code_snippet: #include<stdio.h>
#include<string.h>
#include <algorithm>

int mymax=1000000000;
void moveCheck(int moves[101],int bill[101],int n){
	for(int i=0;i<n-1;i++){
		//òqðoé
		if(bill[i]==1 && bill[i+1]==1){
			moves[i+1]=std::min(moves[i],moves[i+1]);
			moves[i]=mymax;
		}
	}
	for(int i=n-1;i>=1;i--){
		//éÇð~èé
		if(bill[i]==2){
			moves[i-1]=std::min(moves[i],moves[i-1]);
			moves[i]=mymax;
		}
	}
}

void jumpMove(int moves[2][101],int n,int now){
	int next=(now+1)%2;
	for(int i=0;i<n-1;i++){
		for(int k=0;k<3;k++){
			if(i+k>=n) continue;
			moves[next][i+k]=std::min(moves[next][i+k],moves[now][i]+1);
		}
	}
}

void setData(int n){
	int bills[2][101];
	int moves[2][101];
	for(int i=0;i<2*n;i++){
		scanf("%d",&bills[i/n][i%n]);
		moves[i/n][i%n]=mymax;
	}
	moves[0][0]=moves[1][0]=0;
    
    int ans=mymax;
	moveCheck(moves[0],bills[0],n);//¢«ÈèÍµ²ÅBÅ«éÂ\«ðl¶
	moveCheck(moves[1],bills[1],n);
	
	for(int i=0;i<2*n+3;i++){
		ans=std::min(moves[0][n-1],moves[1][n-1]);
		jumpMove(moves,n,0);//0ÔÚÌr©çPÔÚÌrÖÌÚ®
		moveCheck(moves[1],bills[1],n);
		jumpMove(moves,n,1);//1ÔÚ¯ã
		moveCheck(moves[0],bills[0],n);
	}
	if(ans==mymax){
		printf("NA\n");
	}else{
		printf("%d\n",ans);
	}
}

int main(){
	int n;
	while(1){
		scanf("%d",&n);
		if(n==0) break;
		setData(n);
	}
}
accuracy: 1
time_ms: 10
memory_kb: 0
final_rank: 1