Problem:
11 パズル
太郎君は 8 パズルが大得意で休み時間などにいつも友達に並び替えてもらって遊んでいます。そんなとき、友達から「もっと複雑なパズルは解ける?」と聞かれたのですが、他のパズルはやったことはありません。どうやらその友達は自作で 11 パズルを作っていたみたいです。そのパズルは以下のような形をしています。
11 パズルは 11 枚の正方形のカードと、図 1 のような形の枠を使って行います。最初に 11 枚のカードを枠に入れます。すると 2 カ所の空きスペースができますので、この空きスペースに隣接したカードを動かすことができます。これを繰り返し、カードをきれいに整列して、図 2 の完成型にすることが 11 パズルの目的です。
太郎君はこのパズルに挑戦することにしました。ところが太郎君はこの 11 パズルをいとも簡単に解いてしまいました。そこで友達は「動かす数を一番少なくして解いてよ!」と無茶なことを言ってきました。太郎君は答えがわからないので、プログラムのできるあなたに 11 パズルを解くときの最小ステップ数を出すプログラムを作成してもらってから挑戦することにしました。このとき、2 カ所動かせるところがあるのですが、一つの数字を 1 スペース分移動させることを1ステップとして考えることとします。
11 パズルの初期状態を入力とし、11 パズルを解くときの最小ステップ数を出力するプログラムを作成してください。ただし、パズルを解くときの最小ステップ数が 20 ステップより多くかかってしまう場合は、「NA」と出力してください。パズルの状態は、一行目の情報から順に入力されるものとし、数字の 0 は空きスペースを表します。例えば、図 1 の状態を表す入力は以下のようになります。
6
2 1 3
10 5 7 0 8
9 4 11
0
Input
複数のデータセットの並びが入力として与えられます。入力の終わりは-1ひとつの行で示されます。 各データセットは以下の形式で与えられます。
p
1
p
2
p
3
p
4
p
5
p
6
p
7
p
8
p
9
p
10
p
11
p
12
p
13
i
行目にパズルの
i
行目の情報
p
i
(0 ≤
p
i
≤ 11) が空白区切りで与えられます。
データセットの数は 100 を超えません。
Output
データセット毎に、最小ステップ数または NA を１行に出力します。
Sample Input
2
1 0 3
4 5 6 7 8
9 0 11
10
0
1 2 3
4 5 6 7 8
9 10 11
0
0
11 10 9
8 7 6 5 4
3 2 1
0
-1
Output for the Sample Input
2
0
NA

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main(){
    array<int, 13> a;
    array<int, 13> b{0,1,2,3,4,5,6,7,8,9,10,11,0};
    //    0
    //  1 2  3
    //4 5 6  7  8
    //  9 10 11
    //    12
    vector<vector<int>> g = {
        {2},
        {2, 5},
        {0, 1, 3, 6},
        {2, 7},
        {5},
        {1, 4, 6, 9},
        {2, 5, 7, 10},
        {3, 6, 8, 11},
        {7},
        {5, 10},
        {6, 9, 11, 12},
        {7, 10},
        {10}
    };
    map<array<int,13>,int> mp;
    queue<array<int,13>> nxt;
    mp[b] = 0;
    nxt.push(b);
    while(!nxt.empty()){
        a = nxt.front();
        nxt.pop();
        int d = mp[a];
        if(d >= 13)continue;
        for(int i = 0; i < 13; i++){
            if(a[i] != 0)continue;
            for(auto &&j:g[i]){
                swap(a[i], a[j]);
                if(mp.find(a) == mp.end()){
                    mp[a] = d + 1;
                    nxt.push(a);
                }
                swap(a[i], a[j]);
            }
        }
    }
    while(cin >> a[0], a[0] != -1){
        for(int i = 1; i < 13; i++)cin >> a[i];
        if(mp.find(a) != mp.end()){
            cout << mp[a] << '\n';
            continue;
        }
        map<array<int,13>,int> mp2;
        mp2[a] = 0;
        nxt.push(a);
        int ans = 21;
        while(!nxt.empty()){
            a = nxt.front();
            nxt.pop();
            int d = mp2[a];
            if(mp.find(a) != mp.end()){
                ans = min(ans, d + mp[a]);
                continue;
            }
            if(d >= 7)continue;
            for(int i = 0; i < 13; i++){
                if(a[i] != 0)continue;
                for(auto &&j:g[i]){
                    swap(a[i], a[j]);
                    if(mp2.find(a) == mp2.end()){
                        mp2[a] = d + 1;
                        nxt.push(a);
                    }
                    swap(a[i], a[j]);
                }
            }
        }
        if(ans > 20)cout << "NA" << '\n';
        else cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 80
memory_kb: 11860
final_rank: 15

code_snippet: #include<iostream>
#include<vector>
#include<queue>
#include<set>
#include<map>
using namespace std;
//arr[i]…位置iから動ける位置
int arr[13][4]={
	{2,-1,-1,-1},
	{2,5,-1,-1},
	{0,1,3,6},
	{2,7,-1,-1},
	{5,-1,-1,-1},
	{1,4,6,9},
	{2,5,7,10},
	{3,6,8,11},
	{7,-1,-1,-1},
	{5,10,-1,-1},
	{6,9,11,12},
	{7,10,-1,-1},
	{10,-1,-1,-1},
};
//dx[i],dy[i]…位置iの座標
int dx[]={0,1,1,1,2,2,2,2,2,3,3,3,4},dy[]={2,1,2,3,0,1,2,3,4,1,2,3,2};
//位置iと位置jの距離
int dist(int i,int j){
	return abs(dx[i]-dx[j])+abs(dy[i]-dy[j]);
}
//パズルの状態を表す構造体
struct board{
	int val[13];
	//setやmapを使う用
	bool operator<(const board&b)const{
		for(int i=0;i<13;i++)
			if(val[i]!=b.val[i])
				return val[i]<b.val[i];
		return 0;
	}
	//残り最低でも何手かかるかの評価
	int h(){
		int res=0;
		for(int i=0;i<13;i++){
			if(val[i]==0)
				continue;
			res+=dist(val[i],i);
		}
		return res;
	}
	//完成形かどうか
	bool end(){
		int res=1;
		for(int i=0;i<13;i++)
			res&=val[i]==i%12;
		return res;
	}
	//1手進めた形(一覧)
	vector<board>next(){
		vector<board>res;
		//空白がどこか
		int sp=-1,sp2;
		for(int i=0;i<13;i++){
			if(val[i]==0){
				if(sp==-1)
					sp=i;
				else
					sp2=i;
			}
		}
		//1つ目の空白を使う
		for(int i=0;i<4;i++){
			int nsp=arr[sp][i];
			if(nsp==-1)
				continue;
			board tmp=*this;
			swap(tmp.val[sp],tmp.val[nsp]);
			res.push_back(tmp);
		}
		//2つ目の空白を使う
		for(int i=0;i<4;i++){
			int nsp=arr[sp2][i];
			if(nsp==-1)
				continue;
			board tmp=*this;
			swap(tmp.val[sp2],tmp.val[nsp]);
			res.push_back(tmp);
		}
		return res;
	}
};
signed main(){
	board puzzle;
	while(cin>>puzzle.val[0],puzzle.val[0]!=-1){
		for(int i=1;i<13;i++)
			cin>>puzzle.val[i];
		map<board,int>dist;
		set<board>used;
		queue<board>que;
		bool fnd=0;
		//初期状態
		dist[puzzle]=0;
		used.insert(puzzle);
		que.push(puzzle);
		while(!que.empty()){
			puzzle=que.front();
			que.pop();
			//枝刈り
			if(puzzle.h()+dist[puzzle]>=21)
				continue;
			//完成
			if(puzzle.end()){
				cout<<dist[puzzle]<<endl;
				fnd=1;
				break;
			}
			auto nxt=puzzle.next();
			for(const auto&x:nxt){
				//既に見たことがあるならスキップ
				if(used.find(x)!=used.end())
					continue;
				used.insert(x);
				dist[x]=dist[puzzle]+1;
				que.push(x);
			}
		}
		//見つからなかった
		if(!fnd)
			cout<<"NA"<<endl;
	}
}
accuracy: 1
time_ms: 90
memory_kb: 5480
final_rank: 10

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;

template <class T, class U>
vector<T> make_v(U size, const T& init){ return vector<T>(static_cast<size_t>(size), init); }

template<class... Ts, class U>
auto make_v(U size, Ts... rest) { return vector<decltype(make_v(rest...))>(static_cast<size_t>(size), make_v(rest...)); }

template<class T> void chmin(T &a, const T &b){ a = (a < b ? a : b); }
template<class T> void chmax(T &a, const T &b){ a = (a > b ? a : b); }

int main() {
    vector<vector<int>> G{{2},{2, 5},{0, 1, 3, 6},{2, 7},{5},{1, 4, 6, 9},{2, 5, 7, 10},{3, 6, 8, 11},{7},{5, 10},{6, 9, 11, 12},{7, 10},{10}};
    vector<int> y{0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4}, x{2, 1, 2, 3, 0, 1, 2, 3, 4, 1, 2, 3, 2};
    using P = array<int, 13>;
    P v{};
    iota(v.begin(), v.end(), 0);
    v.back() = 0;
    map<P, int> A;
    auto dfs1 = [&](int a, int b, int cur, auto &&f) -> void {
        if(!A.count(v)) A[v] = cur;
        else chmin(A[v], cur);
        if(cur >= 5) return;
        for (auto &&j : G[a]) {
            if(j != b){
                swap(v[a], v[j]);
                f(j, b, cur+1, f);
                swap(v[a], v[j]);
            }
        }
        for (auto &&j : G[b]) {
            if(j != a){
                swap(v[b], v[j]);
                f(a, j, cur+1, f);
                swap(v[b], v[j]);
            }
        }
        return;
    };
    dfs1(0, 12, 0, dfs1);
    while(cin >> v[0], ~v[0]){
        for (int i = 1; i < 13; ++i) cin >> v[i];
        int ans = 21;
        auto dfs = [&](int cur, auto &&f) -> void {
            if(cur+5 >= ans) return;
            if(A.count(v)) {
                chmin(ans, A[v]+cur);
                return;
            }
            int d = 0, a = -1, b = -1;
            for (int i = 0; i < 13; ++i) {
                if(v[i]) d += abs(y[i]-y[v[i]])+abs(x[i]-x[v[i]]);
                else if(!~a) a = i;
                else b = i;
            }
            if(d+cur >= ans) return;
            for (auto &&j : G[a]) {
                if(j != b){
                    swap(v[a], v[j]);
                    f(cur+1, f);
                    swap(v[a], v[j]);
                }
            }
            for (auto &&j : G[b]) {
                if(j != a){
                    swap(v[b], v[j]);
                    f(cur+1, f);
                    swap(v[b], v[j]);
                }
            }

        };
        dfs(0, dfs);
        if(ans == 21) puts("NA");
        else cout << ans << "\n";
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3068
final_rank: 1

code_snippet: #include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <bitset>
#include <cmath>

static const int MOD = 1000000007;
using ll = long long;
using u32 = unsigned;
using u64 = unsigned long long;
using namespace std;

template<class T> constexpr T INF = ::numeric_limits<T>::max()/32*15+208;

template <class T, class U>
vector<T> make_v(U size, const T& init){ return vector<T>(static_cast<size_t>(size), init); }

template<class... Ts, class U>
auto make_v(U size, Ts... rest) { return vector<decltype(make_v(rest...))>(static_cast<size_t>(size), make_v(rest...)); }

template<class T> void chmin(T &a, const T &b){ a = (a < b ? a : b); }
template<class T> void chmax(T &a, const T &b){ a = (a > b ? a : b); }

int main() {
    vector<vector<int>> G{{2},{2, 5},{0, 1, 3, 6},{2, 7},{5},{1, 4, 6, 9},{2, 5, 7, 10},{3, 6, 8, 11},{7},{5, 10},{6, 9, 11, 12},{7, 10},{10}};
    vector<int> y{0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4}, x{2, 1, 2, 3, 0, 1, 2, 3, 4, 1, 2, 3, 2};
    using P = array<int, 13>;
    P v{};
    iota(v.begin(), v.end(), 0);
    v.back() = 0;
    map<P, int> A;
    auto dfs1 = [&](int a, int b, int cur, auto &&f) -> void {
        if(!A.count(v)) A[v] = cur;
        else chmin(A[v], cur);
        if(cur >= 10) return;
        for (auto &&j : G[a]) {
            if(j != b){
                swap(v[a], v[j]);
                f(j, b, cur+1, f);
                swap(v[a], v[j]);
            }
        }
        for (auto &&j : G[b]) {
            if(j != a){
                swap(v[b], v[j]);
                f(a, j, cur+1, f);
                swap(v[b], v[j]);
            }
        }
        return;
    };
    dfs1(0, 12, 0, dfs1);
    while(cin >> v[0], ~v[0]){
        for (int i = 1; i < 13; ++i) cin >> v[i];
        int ans = 21;
        auto dfs = [&](int cur, auto &&f) -> void {
            if(cur+10 >= ans) return;
            if(A.count(v)) {
                chmin(ans, A[v]+cur);
                return;
            }
            int d = 0, a = -1, b = -1;
            for (int i = 0; i < 13; ++i) {
                if(v[i]) d += abs(y[i]-y[v[i]])+abs(x[i]-x[v[i]]);
                else if(!~a) a = i;
                else b = i;
            }
            if(d+cur >= ans) return;
            for (auto &&j : G[a]) {
                if(j != b){
                    swap(v[a], v[j]);
                    f(cur+1, f);
                    swap(v[a], v[j]);
                }
            }
            for (auto &&j : G[b]) {
                if(j != a){
                    swap(v[b], v[j]);
                    f(cur+1, f);
                    swap(v[b], v[j]);
                }
            }

        };
        dfs(0, dfs);
        if(ans == 21) puts("NA");
        else cout << ans << "\n";
    }
    return 0;
}
accuracy: 1
time_ms: 1500
memory_kb: 3908
final_rank: 18

code_snippet: #include<iostream>
#include<queue>
#include<map>
#include<vector>
using namespace std;
int px[13]={0,1,1,1,2,2,2,2,2,3,3,3,4},py[13]={2,1,2,3,0,1,2,3,4,1,2,3,2};
int xx[12]={0,1,1,1,2,2,2,2,2,3,3,3},yy[12]={0,1,2,3,0,1,2,3,4,1,2,3};
struct board{
	int p[13],a,b;
	bool operator<(const board&a)const
	{
		for(int i=0;i<13;i++)
		{
			if(p[i]!=a.p[i])return p[i]<a.p[i];
		}
		return false;
	}
	int distance()const
	{
		int ret=0;
		for(int i=0;i<13;i++)
		{
			if(p[i]==0)continue;
			ret+=abs(px[i]-xx[p[i]])+abs(py[i]-yy[p[i]]);
		}
		return ret;
	}
};
vector<int>D[13];
main()
{
	D[0].push_back(2);
	D[1].push_back(2);
	D[1].push_back(5);
	D[2].push_back(0);
	D[2].push_back(1);
	D[2].push_back(3);
	D[2].push_back(6);
	D[3].push_back(2);
	D[3].push_back(7);
	D[4].push_back(5);
	D[5].push_back(1);
	D[5].push_back(4);
	D[5].push_back(6);
	D[5].push_back(9);
	D[6].push_back(2);
	D[6].push_back(5);
	D[6].push_back(7);
	D[6].push_back(10);
	D[7].push_back(3);
	D[7].push_back(6);
	D[7].push_back(8);
	D[7].push_back(11);
	D[8].push_back(7);
	D[9].push_back(5);
	D[9].push_back(10);
	D[10].push_back(6);
	D[10].push_back(9);
	D[10].push_back(11);
	D[10].push_back(12);
	D[11].push_back(7);
	D[11].push_back(10);
	D[12].push_back(10);
	while(true)
	{
		board start;
		cin>>start.p[0];
		if(start.p[0]<0)break;
		for(int i=1;i<13;i++)cin>>start.p[i];
		start.a=start.b=-1;
		for(int i=0;i<13;i++)
		{
			if(start.p[i]==0)
			{
				if(start.a<0)start.a=i;
				else start.b=i;
			}
		}
		board goal;
		for(int i=0;i<12;i++)goal.p[i]=i;
		goal.p[12]=0;
		queue<board>P;
		P.push(start);
		map<board,int>M;
		M[start]=0;
		int ans=-1;
		while(!P.empty())
		{
			board now=P.front();P.pop();
			int c=M[now];
			if(c+now.distance()>20)continue;
			if(!(now<goal||goal<now))
			{
				ans=c;
				break;
			}
			for(int v:D[now.a])
			{
				int x=now.a,y=v;
				swap(now.p[x],now.p[y]);
				now.a=y;
				if(M.find(now)==M.end())
				{
					M[now]=c+1;
					P.push(now);
				}
				swap(now.p[x],now.p[y]);
				now.a=x;
			}
			for(int v:D[now.b])
			{
				int x=now.b,y=v;
				swap(now.p[x],now.p[y]);
				now.b=y;
				if(M.find(now)==M.end())
				{
					M[now]=c+1;
					P.push(now);
				}
				swap(now.p[x],now.p[y]);
				now.b=x;
			}
		}
		if(ans<0)cout<<"NA"<<endl;
		else cout<<ans<<endl;
	}
}
accuracy: 1
time_ms: 70
memory_kb: 4516
final_rank: 8

code_snippet: #include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
const int lim = 20;
const vector<int> bx = { 0, 4, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3 };
const vector<int> by = { 2, 2, 1, 2, 3, 0, 1, 2, 3, 4, 1, 2, 3 };
struct state {
	vector<int> px, py;
	int cost, rem, last1, last2;
};
bool operator<(const state& s1, const state& s2) {
	return s1.cost + s1.rem != s2.cost + s2.rem ? s1.cost + s1.rem > s2.cost + s2.rem : s1.rem > s2.rem;
}
int eval(vector<int> px, vector<int> py) {
	int ret = 0;
	for (int i = 2; i < 13; ++i) {
		ret += abs(px[i] - bx[i]) + abs(py[i] - by[i]);
	}
	return ret;
}
int main() {
	int x;
	while (cin >> x, x != -1) {
		vector<int> vx(13), vy(13);
		int zc = 0;
		vx[x == 0 ? zc : x + 1] = bx[0];
		vy[x == 0 ? zc : x + 1] = by[0];
		if (x == 0) ++zc;
		for (int i = 1; i < 13; ++i) {
			cin >> x;
			vx[x == 0 ? zc : x + 1] = bx[i == 12 ? 1 : i + 1];
			vy[x == 0 ? zc : x + 1] = by[i == 12 ? 1 : i + 1];
			if (x == 0) ++zc;
		}
		priority_queue<state> que;
		que.push(state{ vx, vy, 0, eval(vx, vy), -1, -1 });
		int ans = -1;
		while (!que.empty()) {
			state u = que.top();
			que.pop();
			if (u.rem == 0) {
				ans = u.cost;
				break;
			}
			for (int i = 0; i < 2; ++i) {
				for (int j = 2; j < 13; ++j) {
					if (i == u.last1 && j == u.last2) continue;
					if (abs(u.px[i] - u.px[j]) + abs(u.py[i] - u.py[j]) == 1) {
						swap(u.px[i], u.px[j]);
						swap(u.py[i], u.py[j]);
						int ev = eval(u.px, u.py);
						if (u.cost + ev + 1 <= lim) {
							que.push(state{ u.px, u.py, u.cost + 1, eval(u.px, u.py), i, j });
						}
						swap(u.px[i], u.px[j]);
						swap(u.py[i], u.py[j]);
					}
				}
			}
		}
		if (ans != -1) cout << ans << endl;
		else cout << "NA" << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3948
final_rank: 7

code_snippet: #include<bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
typedef pair<vector<int>,int>P;
vector<int>v[13],s(13),t(13);
map<vector<int>,int>m;
 
int has[14];
 
 
void init(){
 
    v[0].push_back(2);
 
    v[1].push_back(2);
    v[1].push_back(5);
 
    v[2].push_back(0);
    v[2].push_back(1);
    v[2].push_back(3);
    v[2].push_back(6);
 
    v[3].push_back(2);
    v[3].push_back(7);
 
    v[4].push_back(5);
 
    v[5].push_back(1);
    v[5].push_back(4);
    v[5].push_back(6);
    v[5].push_back(9);
 
    v[6].push_back(2);
    v[6].push_back(5);
    v[6].push_back(7);
    v[6].push_back(10);
 
    v[7].push_back(3);
    v[7].push_back(6);
    v[7].push_back(8);
    v[7].push_back(11);
 
    v[8].push_back(7);
 
    v[9].push_back(5);
    v[9].push_back(10);
 
    v[10].push_back(6);
    v[10].push_back(9);
    v[10].push_back(11);
    v[10].push_back(12);
 
    v[11].push_back(7);
    v[11].push_back(10);
 
    v[12].push_back(10);
 
    int a=20;
    int p=1;
 
    r(i,13){
        has[i]=p;
        p*=a;
    }
}
 
int ha(vector<int> &x){
 
    int re=0;
 
    r(i,13){
        re+=x[i]*has[i];
    }
 
    return re;
}
 
vector<int> ah(int x){
    vector<int>y(13);
    r(i,13){
        y[i]=x%20;
        x/=20;
    }
    return y;
}
 
void BFS1(){
    s[0]=0;
    s[12]=0;
    r(i,11)s[i+1]=i+1;
    set<vector<int> >st;
    st.insert(s);
    m[s]=0;
    queue<P>q;
    q.push(P(s,0));
    while(1){
        vector<int> now=q.front().first;
        int cost=q.front().second;
        q.pop();
        if(cost==11)break;
        //cout<<m.size()<<' '<<cost<<endl;
        r(i,13)if(now[i]==0){
            r(j,v[i].size()){
                swap(now[i],now[v[i][j]]);
                if(!st.count(now)){
                    st.insert(now);
                    m[now]=cost+1;
                    q.push(P(now,cost+1));
                }
                swap(now[i],now[v[i][j]]);
            }
        }
    }
}
 
void BFS2(){
    set<vector<int> >st;
    st.insert(t);
    queue<P>q;
    q.push(P(t,0));
    while(1){
        vector<int>now=q.front().first;
        int cost=q.front().second;
        q.pop();
        if(m.count(now)){
            cout<<m[now]+cost<<endl;
            return ;
        }
        if(cost==9)break;
        r(i,13)if(now[i]==0){
            r(j,v[i].size()){
                swap(now[i],now[v[i][j]]);
                if(!st.count(now)){
                    st.insert(now);
                    if(m.count(now)){
                        cout<<m[now]+cost+1<<endl;
                        return ;
                    }
                    q.push(P(now,cost+1));
                }
                swap(now[i],now[v[i][j]]);
            }
        }
    }
    cout<<"NA"<<endl;
}
 
 
signed main(){
    init();
    BFS1();
    while(cin>>t[0],t[0]!=-1){
        r(i,12)cin>>t[i+1];
        BFS2();
    }
}
accuracy: 1
time_ms: 200
memory_kb: 8612
final_rank: 13

code_snippet: #include<bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
typedef pair<vector<int>,int>P;
vector<int>v[13],s(13),t(13);
map<vector<int>,int>m;
 
int has[14];
 
 
void init(){
 
    v[0].push_back(2);
 
    v[1].push_back(2);
    v[1].push_back(5);
 
    v[2].push_back(0);
    v[2].push_back(1);
    v[2].push_back(3);
    v[2].push_back(6);
 
    v[3].push_back(2);
    v[3].push_back(7);
 
    v[4].push_back(5);
 
    v[5].push_back(1);
    v[5].push_back(4);
    v[5].push_back(6);
    v[5].push_back(9);
 
    v[6].push_back(2);
    v[6].push_back(5);
    v[6].push_back(7);
    v[6].push_back(10);
 
    v[7].push_back(3);
    v[7].push_back(6);
    v[7].push_back(8);
    v[7].push_back(11);
 
    v[8].push_back(7);
 
    v[9].push_back(5);
    v[9].push_back(10);
 
    v[10].push_back(6);
    v[10].push_back(9);
    v[10].push_back(11);
    v[10].push_back(12);
 
    v[11].push_back(7);
    v[11].push_back(10);
 
    v[12].push_back(10);
 
    int a=20;
    int p=1;
 
    r(i,13){
        has[i]=p;
        p*=a;
    }
}
 
int ha(vector<int> &x){
 
    int re=0;
 
    r(i,13){
        re+=x[i]*has[i];
    }
 
    return re;
}
 
vector<int> ah(int x){
    vector<int>y(13);
    r(i,13){
        y[i]=x%20;
        x/=20;
    }
    return y;
}
 
void BFS1(){
    s[0]=0;
    s[12]=0;
    r(i,11)s[i+1]=i+1;
    set<vector<int> >st;
    st.insert(s);
    m[s]=0;
    queue<P>q;
    q.push(P(s,0));
    while(1){
        vector<int> now=q.front().first;
        int cost=q.front().second;
        q.pop();
        if(cost==13)break;
        //cout<<m.size()<<' '<<cost<<endl;
        r(i,13)if(now[i]==0){
            r(j,v[i].size()){
                swap(now[i],now[v[i][j]]);
                if(!st.count(now)){
                    st.insert(now);
                    m[now]=cost+1;
                    q.push(P(now,cost+1));
                }
                swap(now[i],now[v[i][j]]);
            }
        }
    }
}
 
void BFS2(){
    set<vector<int> >st;
    st.insert(t);
    queue<P>q;
    q.push(P(t,0));
    while(1){
        vector<int>now=q.front().first;
        int cost=q.front().second;
        q.pop();
        if(m.count(now)){
            cout<<m[now]+cost<<endl;
            return ;
        }
        if(cost==7)break;
        r(i,13)if(now[i]==0){
            r(j,v[i].size()){
                swap(now[i],now[v[i][j]]);
                if(!st.count(now)){
                    st.insert(now);
                    if(m.count(now)){
                        cout<<m[now]+cost+1<<endl;
                        return ;
                    }
                    q.push(P(now,cost+1));
                }
                swap(now[i],now[v[i][j]]);
            }
        }
    }
    cout<<"NA"<<endl;
}
 
 
signed main(){
    init();
    BFS1();
    while(cin>>t[0],t[0]!=-1){
        r(i,12)cin>>t[i+1];
        BFS2();
    }
}
accuracy: 1
time_ms: 160
memory_kb: 25348
final_rank: 19

code_snippet: #include<bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
typedef pair<vector<int>,int>P;
vector<int>v[13],s(13),t(13);
map<vector<int>,int>m;
 
int has[14];
 
 
void init(){
 
    v[0].push_back(2);
 
    v[1].push_back(2);
    v[1].push_back(5);
 
    v[2].push_back(0);
    v[2].push_back(1);
    v[2].push_back(3);
    v[2].push_back(6);
 
    v[3].push_back(2);
    v[3].push_back(7);
 
    v[4].push_back(5);
 
    v[5].push_back(1);
    v[5].push_back(4);
    v[5].push_back(6);
    v[5].push_back(9);
 
    v[6].push_back(2);
    v[6].push_back(5);
    v[6].push_back(7);
    v[6].push_back(10);
 
    v[7].push_back(3);
    v[7].push_back(6);
    v[7].push_back(8);
    v[7].push_back(11);
 
    v[8].push_back(7);
 
    v[9].push_back(5);
    v[9].push_back(10);
 
    v[10].push_back(6);
    v[10].push_back(9);
    v[10].push_back(11);
    v[10].push_back(12);
 
    v[11].push_back(7);
    v[11].push_back(10);
 
    v[12].push_back(10);
 
    int a=20;
    int p=1;
 
    r(i,13){
        has[i]=p;
        p*=a;
    }
}
 
int ha(vector<int> &x){
 
    int re=0;
 
    r(i,13){
        re+=x[i]*has[i];
    }
 
    return re;
}
 
vector<int> ah(int x){
    vector<int>y(13);
    r(i,13){
        y[i]=x%20;
        x/=20;
    }
    return y;
}
 
void BFS1(){
    s[0]=0;
    s[12]=0;
    r(i,11)s[i+1]=i+1;
    set<vector<int> >st;
    st.insert(s);
    m[s]=0;
    queue<P>q;
    q.push(P(s,0));
    while(1){
        vector<int> now=q.front().first;
        int cost=q.front().second;
        q.pop();
        if(cost==12)break;
        //cout<<m.size()<<' '<<cost<<endl;
        r(i,13)if(now[i]==0){
            r(j,v[i].size()){
                swap(now[i],now[v[i][j]]);
                if(!st.count(now)){
                    st.insert(now);
                    m[now]=cost+1;
                    q.push(P(now,cost+1));
                }
                swap(now[i],now[v[i][j]]);
            }
        }
    }
}
 
void BFS2(){
    set<vector<int> >st;
    st.insert(t);
    queue<P>q;
    q.push(P(t,0));
    while(1){
        vector<int>now=q.front().first;
        int cost=q.front().second;
        q.pop();
        if(m.count(now)){
            cout<<m[now]+cost<<endl;
            return ;
        }
        if(cost==8)break;
        r(i,13)if(now[i]==0){
            r(j,v[i].size()){
                swap(now[i],now[v[i][j]]);
                if(!st.count(now)){
                    st.insert(now);
                    if(m.count(now)){
                        cout<<m[now]+cost+1<<endl;
                        return ;
                    }
                    q.push(P(now,cost+1));
                }
                swap(now[i],now[v[i][j]]);
            }
        }
    }
    cout<<"NA"<<endl;
}
 
 
signed main(){
    init();
    BFS1();
    while(cin>>t[0],t[0]!=-1){
        r(i,12)cin>>t[i+1];
        BFS2();
    }
}
accuracy: 1
time_ms: 140
memory_kb: 14412
final_rank: 16

code_snippet: #include<bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
typedef pair<vector<int>,int>P;
vector<int>v[13],s(13),t(13);
map<vector<int>,int>m;

int has[14];


void init(){

    v[0].push_back(2);

    v[1].push_back(2);
    v[1].push_back(5);

    v[2].push_back(0);
    v[2].push_back(1);
    v[2].push_back(3);
    v[2].push_back(6);

    v[3].push_back(2);
    v[3].push_back(7);

    v[4].push_back(5);

    v[5].push_back(1);
    v[5].push_back(4);
    v[5].push_back(6);
    v[5].push_back(9);

    v[6].push_back(2);
    v[6].push_back(5);
    v[6].push_back(7);
    v[6].push_back(10);

    v[7].push_back(3);
    v[7].push_back(6);
    v[7].push_back(8);
    v[7].push_back(11);

    v[8].push_back(7);

    v[9].push_back(5);
    v[9].push_back(10);

    v[10].push_back(6);
    v[10].push_back(9);
    v[10].push_back(11);
    v[10].push_back(12);

    v[11].push_back(7);
    v[11].push_back(10);

    v[12].push_back(10);

    int a=20;
    int p=1;

    r(i,13){
        has[i]=p;
        p*=a;
    }
}

int ha(vector<int> &x){

    int re=0;

    r(i,13){
        re+=x[i]*has[i];
    }

    return re;
}

vector<int> ah(int x){
    vector<int>y(13);
    r(i,13){
        y[i]=x%20;
        x/=20;
    }
    return y;
}

void BFS1(){
    s[0]=0;
    s[12]=0;
    r(i,11)s[i+1]=i+1;
    set<vector<int> >st;
    st.insert(s);
    m[s]=0;
    queue<P>q;
    q.push(P(s,0));
    while(1){
        vector<int> now=q.front().first;
        int cost=q.front().second;
        q.pop();
        if(cost==10)break;
        //cout<<m.size()<<' '<<cost<<endl;
        r(i,13)if(now[i]==0){
            r(j,v[i].size()){
                swap(now[i],now[v[i][j]]);
                if(!st.count(now)){
                    st.insert(now);
                    m[now]=cost+1;
                    q.push(P(now,cost+1));
                }
                swap(now[i],now[v[i][j]]);
            }
        }
    }
}

void BFS2(){
    set<vector<int> >st;
    st.insert(t);
    queue<P>q;
    q.push(P(t,0));
    while(1){
        vector<int>now=q.front().first;
        int cost=q.front().second;
        q.pop();
        if(m.count(now)){
            cout<<m[now]+cost<<endl;
            return ;
        }
        if(cost==10)break;
        r(i,13)if(now[i]==0){
            r(j,v[i].size()){
                swap(now[i],now[v[i][j]]);
                if(!st.count(now)){
                    st.insert(now);
                    if(m.count(now)){
                        cout<<m[now]+cost+1<<endl;
                        return ;
                    }
                    q.push(P(now,cost+1));
                }
                swap(now[i],now[v[i][j]]);
            }
        }
    }
    cout<<"NA"<<endl;
}


signed main(){
    init();
    BFS1();
    while(cin>>t[0],t[0]!=-1){
        r(i,12)cin>>t[i+1];
        BFS2();
    }
}
accuracy: 1
time_ms: 380
memory_kb: 8280
final_rank: 14

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Info{
	short table[5][5];
	int space_row1,space_col1,space_row2,space_col2;
};

map<string,bool> MAP;

bool rangeCheck(int row,int col){
	if(row < 0 || row >= 5)return false;

	switch(row){
	case 0:
		if(col == 2)return true;
		break;
	case 1:
		if(col >= 1 && col <= 3)return true;
		break;
	case 2:
		if(col >= 0 && col <= 4)return true;
		break;
	case 3:
		if(col >= 1 && col <= 3)return true;
		break;
	case 4:
		if(col == 2)return true;
		break;
	}
	return false;
}

bool clearFLG;
int ans;
int p[13];
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};


void copyInfo(Info& to,Info from){

	for(int row = 0; row <= 4; row++){
		for(int col = 0; col <= 4; col++){
			to.table[row][col] = from.table[row][col];
		}
	}
}

int calc_manhattan_sum(Info info){

	int sum = 0;
	for(int row = 0; row <= 4; row++){
		for(int col = 0; col <= 4; col++){
			if(rangeCheck(row,col) == true && info.table[row][col] != 0){
				switch(info.table[row][col]){
				case 1:
					sum += abs(row-1)+abs(col-1);
					break;
				case 2:
					sum += abs(row-1)+abs(col-2);
					break;
				case 3:
					sum += abs(row-1)+abs(col-3);
					break;
				case 4:
					sum += abs(row-2)+abs(col-0);
					break;
				case 5:
					sum += abs(row-2)+abs(col-1);
					break;
				case 6:
					sum += abs(row-2)+abs(col-2);
					break;
				case 7:
					sum += abs(row-2)+abs(col-3);
					break;
				case 8:
					sum += abs(row-2)+abs(col-4);
					break;
				case 9:
					sum += abs(row-3)+abs(col-1);
					break;
				case 10:
					sum += abs(row-3)+abs(col-2);
					break;
				case 11:
					sum += abs(row-3)+abs(col-3);
					break;
				}
			}
		}
	}
	return sum;
}


void recursive(Info info,int depth,int max_depth){

	if(clearFLG)return;

	if(depth == max_depth){
		if(info.table[1][1] == 1 && info.table[1][2] == 2 && info.table[1][3] == 3 &&
				info.table[2][0] == 4 && info.table[2][1] == 5 && info.table[2][2] == 6 && info.table[2][3] == 7 && info.table[2][4] == 8 &&
				info.table[3][1] == 9 && info.table[3][2] == 10 && info.table[3][3] == 11){
			clearFLG = true;
		}
		return;
	}

	int adj_row,adj_col;

	for(int i = 0; i < 4; i++){
		adj_row = info.space_row1+diff_row[i];
		adj_col = info.space_col1+diff_col[i];

		if(rangeCheck(adj_row,adj_col) == false || info.table[adj_row][adj_col] == 0)continue;

		Info next_info;
		copyInfo(next_info,info);

		swap(next_info.table[info.space_row1][info.space_col1],next_info.table[adj_row][adj_col]);

		string tmp;
		for(int row = 0; row <= 4; row++){
			for(int col = 0; col <= 4; col++){
				if(rangeCheck(row,col)){
					tmp.append(to_string(next_info.table[row][col])).append(to_string('*'));
				}
			}
		}

		auto at = MAP.find(tmp);
		if(at != MAP.end())continue;

		MAP[tmp] = true;

		next_info.space_row1 = adj_row;
		next_info.space_col1 = adj_col;
		next_info.space_row2 = info.space_row2;
		next_info.space_col2 = info.space_col2;

		if(max_depth-(depth+1) < calc_manhattan_sum(next_info))continue;

		recursive(next_info,depth+1,max_depth);
	}

	for(int i = 0; i < 4; i++){
		adj_row = info.space_row2+diff_row[i];
		adj_col = info.space_col2+diff_col[i];

		if(rangeCheck(adj_row,adj_col) == false || info.table[adj_row][adj_col] == 0)continue;

		Info next_info;
		copyInfo(next_info,info);

		swap(next_info.table[info.space_row2][info.space_col2],next_info.table[adj_row][adj_col]);

		string tmp;
		for(int row = 0; row <= 4; row++){
			for(int col = 0; col <= 4; col++){
				if(rangeCheck(row,col)){
					tmp.append(to_string(next_info.table[row][col])).append(to_string('*'));
				}
			}
		}

		auto at = MAP.find(tmp);
		if(at != MAP.end())continue;

		MAP[tmp] = true;

		next_info.space_row1 = info.space_row1;
		next_info.space_col1 = info.space_col1;
		next_info.space_row2 = adj_row;
		next_info.space_col2 = adj_col;

		if(max_depth-(depth+1) < calc_manhattan_sum(next_info))continue;

		recursive(next_info,depth+1,max_depth);
	}
}

void func(){

	for(int i = 1; i < 13; i++)scanf("%d",&p[i]);

	Info first;
	first.table[0][2] = p[0];
	for(int i = 1; i <= 3; i++)first.table[1][i] = p[i];
	for(int i = 0; i <= 4; i++)first.table[2][i] = p[4+i];
	for(int i = 1; i <= 3; i++)first.table[3][i] = p[8+i];
	first.table[4][2] = p[12];

	int count = 0;

	for(int row = 0; row <= 4; row++){
		for(int col = 0; col <= 4; col++){
			if(rangeCheck(row,col) == true && first.table[row][col] == 0){
				if(count == 0){
					first.space_row1 = row;
					first.space_col1 = col;
					count++;
				}else{
					first.space_row2 = row;
					first.space_col2 = col;
				}
			}
		}
	}

	clearFLG = false;

	for(int max_depth = 0; max_depth <= 20; max_depth++){
		MAP.clear();

		string tmp;
		for(int row = 0; row <= 4; row++){
			for(int col = 0; col <= 4; col++){
				if(rangeCheck(row,col)){
					tmp.append(to_string(first.table[row][col])).append(to_string('*'));
				}
			}
		}

		MAP[tmp] = true;

		recursive(first,0,max_depth);
		if(clearFLG){
			ans = max_depth;
			break;
		}
	}

	if(clearFLG){
		printf("%d\n",ans);
	}else{
		printf("NA\n");
	}
}

int main(){

	while(true){
		scanf("%d",&p[0]);
		if(p[0] == -1)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3344
final_rank: 6

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
#define fi first
#define se second

template<typename A, typename B> inline bool chmax(A &a, B b) { if (a<b) { a=b; return 1; } return 0; }
template<typename A, typename B> inline bool chmin(A &a, B b) { if (a>b) { a=b; return 1; } return 0; }

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<int, pll> pip;
const ll INF = 1ll<<29;
const ll MOD = 1000000007;
const double EPS  = 1e-9;

int dd[13][4] = {
	{2,-1,-1,-1},
	{2,5,-1,-1},
	{0,1,3,6},
	{2,7,-1,-1},
	{5,-1,-1,-1},
	{1,4,6,9},
	{2,5,7,10},
	{3,6,8,11},
	{7,-1,-1,-1},
	{5,10,-1,-1},
	{6,9,11,12},
	{7,10,-1,-1},
	{10,-1,-1,-1}
};

int main() {
	queue<string> que;
	map<string, int> d;
	
	que.push("abcdefghijkla");
	d["abcdefghijkla"] = 0;
	
	while (!que.empty()) {
		string now = que.front(); que.pop();
		int cost = d[now];
		
		if (cost > 10) break;
		
		REP(i, 13) if (now[i] == 'a') {
			REP(j, 4) {
				if (dd[i][j] == -1) break;
				
				swap(now[i], now[dd[i][j]]);
				if (d.find(now) == d.end()) {
					d[now] = cost + 1;
					que.push(now);
				}
				swap(now[i], now[dd[i][j]]);
			}
		}
	}
	while (!que.empty()) que.pop();
	
	int p[13];
	while (cin >> p[0], ~p[0]) {
		FOR(i, 1, 13) cin >> p[i];
		string st = "";
		REP(i, 13) st += p[i] + 'a';
		
		map<string, int> d2;
		que.push(st);
		d2[st] = 0;
		
		int ans = INF;
		
		while (!que.empty()) {
			string now = que.front(); que.pop();
			int cost = d2[now];
			
			if (cost > 10) break;
			if (d.find(now) != d.end()) chmin(ans, d[now] + d2[now]);
			
			REP(i, 13) if (now[i] == 'a') {
				REP(j, 4) {
					if (dd[i][j] == -1) break;
					
					swap(now[i], now[dd[i][j]]);
					if (d2.find(now) == d2.end()) {
						d2[now] = cost + 1;
						que.push(now);
					}
					swap(now[i], now[dd[i][j]]);
				}
			}
		}
		while (!que.empty()) que.pop();
		
		if (ans <= 20) cout << ans << endl;
		else puts("NA");
	}
	return 0;
}
accuracy: 1
time_ms: 1920
memory_kb: 11456
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;

int fie[5][5];
int o_fie[5][5]={
    -1,-1,0,-1,-1,
    -1,1,2,3,-1,
    4,5,6,7,8,
    -1,9,10,11,-1
    -1,-1,0,-1,-1,
};

int ox[12],oy[12],zx[2],zy[2],zcnt;
int res;
bool flag;

int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};

void dfs(int v,int dist,int pd,int pu){
    if(dist==0){
        flag=true;
        res=min(res,v);
        return;
    }
    for(int i=0;i<4;i++){
        for(int j=0;j<2;j++){
            if(pu==j && (pd+2)%4==i)continue;
            int nx=zx[j]+dx[i],ny=zy[j]+dy[i];
            if(nx>=0 && nx<5 && ny>=0 && ny<5){
                if(fie[nx][ny]<=0)continue;
                int ch=fie[nx][ny];
                int ndist=dist;
                ndist-=abs(ox[ch]-nx)+abs(oy[ch]-ny);
                swap(fie[nx][ny],fie[zx[j]][zy[j]]);
                ndist+=abs(ox[ch]-zx[j])+abs(oy[ch]-zy[j]);
                zx[j]+=dx[i];
                zy[j]+=dy[i];
                if(v+1+ndist<=res)dfs(v+1,ndist,i,j);
                zx[j]-=dx[i];
                zy[j]-=dy[i];
                swap(fie[nx][ny],fie[zx[j]][zy[j]]);
            }
        }
    }
}
int dist;

int main(void){
    for(int i=0;i<5;i++){
        for(int j=abs(2-i);j<=4-abs(2-i);j++){
            ox[o_fie[i][j]]=j;
            oy[o_fie[i][j]]=i;
        }
    }
    while(1){
        memset(fie,-1,sizeof(fie));
        dist=0;
        zcnt=0;
        for(int i=0;i<5;i++){
            for(int j=abs(2-i);j<=4-abs(2-i);j++){
                scanf("%d",&fie[j][i]);
                if(fie[j][i]==-1)return 0;
            }
        }
        for(int i=0;i<5;i++){
            for(int j=abs(2-i);j<=4-abs(2-i);j++){
                int v=fie[j][i];
                if(v==0){
                    zx[zcnt]=j;
                    zy[zcnt++]=i;
                }else dist+=abs(ox[v]-j)+abs(oy[v]-i);
            }
        }
        if(dist>20){
            printf("NA\n");
        }else{
            int i=0;
            flag=false;
            res=20;
            dfs(0,dist,-1,-1);
            if(flag){
                printf("%d\n",res);
            }
            if(!flag)printf("NA\n");
        }
    }
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3140
final_rank: 5

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define int long long
#define FR first
#define SC second
#define all(v) (v).begin(), (v).end()
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define reps(i, f, n) for(int i = (int)(f); i < (int)(n); i++)
#define each(a, b) for(auto& a : b)

typedef pair<int, int> P;

const int inf = 1LL << 55;

vector< vector<int> > to = {
  {2},
  {2, 5},
  {0, 1, 3, 6},
  {2, 7},
  {5},
  {1, 4, 6, 9},
  {2, 5, 7, 10},
  {3, 6, 8, 11},
  {7},
  {5, 10},
  {6, 9, 11, 12},
  {7, 10},
  {10}
};

vector<int> ans = {0,1,2,3,4,5,6,7,8,9,10,11,0};

vector<int> x = {2,1,2,3,0,1,2,3,4,1,2,3,2};
vector<int> y = {0,1,1,1,2,2,2,2,2,3,3,3,4};

signed main()
{
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  int p;
  while(cin >> p, ~p) {
    vector<int> pzl; pzl.push_back(p);
    rep(i, 12) cin >> p, pzl.push_back(p);
    map<vector<int>, int> d;
    queue< vector<int> > que;
    que.push(pzl);
    d[pzl] = 0;
    bool flag = false;
    while(!que.empty() && !flag) {
      auto v = que.front(); que.pop();
      int e = 0;
      rep(i, v.size()) if(v[i]) {
	e += abs(x[i]-x[v[i]]) + abs(y[i]-y[v[i]]);
      }
      if(e == 0) {
	cout << d[v] << endl;
	flag = true;
	break;
      }
      if(e + d[v] > 20) continue;
      rep(i, v.size()) {
	if(v[i]) continue;
	rep(j, to[i].size()) {
	  int c = d[v];
	  swap(v[i], v[to[i][j]]);
	  if(!d.count(v)) {
	    que.push(v);
	    d[v] = c + 1;
	  }
	  swap(v[i], v[to[i][j]]);
	}
      }
    }
    if(!flag) cout << "NA" << endl;
  }
  
  return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 5468
final_rank: 11

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define int long long
#define FR first
#define SC second
#define all(v) (v).begin(), (v).end()
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define reps(i, f, n) for(int i = (int)(f); i < (int)(n); i++)
#define each(a, b) for(auto& a : b)

typedef pair<int, int> P;

const int inf = 1LL << 55;

vector< vector<int> > to = {
  {2},
  {2, 5},
  {0, 1, 3, 6},
  {2, 7},
  {5},
  {1, 4, 6, 9},
  {2, 5, 7, 10},
  {3, 6, 8, 11},
  {7},
  {5, 10},
  {6, 9, 11, 12},
  {7, 10},
  {10}
};

vector<int> ans = {0,1,2,3,4,5,6,7,8,9,10,11,0};

signed main()
{
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  map<vector<int>, int> D;  
  queue< vector<int> > que;
  que.push(ans);
  D[ans] = 0;
  while(!que.empty()) {
    auto v = que.front(); que.pop();
    if(D[v] >= 10) break;
    rep(i, v.size()) {
      if(v[i]) continue;
      rep(j, to[i].size()) {
	int c = D[v];
	swap(v[i], v[to[i][j]]);
	if(!D.count(v)) {
	  que.push(v);
	  D[v] = c + 1;
	}
	swap(v[i], v[to[i][j]]);
      }
    }
  }
  
  int p;
  while(cin >> p, ~p) {
    vector<int> pzl; pzl.push_back(p);
    rep(i, 12) cin >> p, pzl.push_back(p);
    if(D.count(pzl)) {
      cout << D[pzl] << endl;
      continue;
    }
    map<vector<int>, int> d;
    queue< vector<int> > que;
    que.push(pzl);
    d[pzl] = 0;
    bool flag = false;
    while(!que.empty() && !flag) {
      auto v = que.front(); que.pop();
      if(d[v] >= 10) break;      
      rep(i, v.size()) {
	if(v[i]) continue;
	rep(j, to[i].size()) {
	  int c = d[v];
	  swap(v[i], v[to[i][j]]);
	  if(D.count(v)) {
	    cout << D[v] + c + 1 << endl;
	    flag = true;
	    break;
	  } else if(!d.count(v)) {
	    que.push(v);
	    d[v] = c + 1;
	  }
	  swap(v[i], v[to[i][j]]);
	}
	if(flag) break;
      }
    }
    if(!flag) cout << "NA" << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 530
memory_kb: 11232
final_rank: 17

code_snippet: #include <iostream>
#include <vector>

using namespace std;
 
struct P {
    int x, y;
    P(int x, int y) : x{x}, y{y} {}
};
 
int limit;
vector<int> v;

constexpr int X[] = {2, 1, 2, 3, 0, 1, 2, 3, 4, 1, 2, 3, 2};
constexpr int Y[] = {0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4};
 
int next_pos(int x, int y)
{
    for (int i = 0; i < 13; i++) {
        if (x == X[i] && y == Y[i]) {
            return i;
        }
    }        
    return -1;
}
 
int getMD()
{
    int sum = 0;
    for (int i = 0; i < 13; i++) {
        if (v[i] == 0) continue;
        sum += abs(X[i] - X[v[i]]) + abs(Y[i] - Y[v[i]]);
    }
    return sum;
}
 
constexpr int dx[] = {-1, 0, 1, 0};
constexpr int dy[] = {0, -1, 0, 1};
 
bool dfs(const int* sp, int step)
{
    int md = getMD();
    if (md == 0) return 1;
    if (md + step > limit) {
        return 0;
    }
    
    for (int i = 0; i < 2; i++) {
        int x = X[sp[i]], y = Y[sp[i]];
        for (int j = 0; j < 4; j++) {
            int nx = x + dx[j], ny = y + dy[j];
            int next = next_pos(nx, ny);
            if (next == -1) continue;
            
            const int nsp1[] = {next, sp[1]}, nsp2[] = {sp[0], next};
            
            swap(v[sp[i]], v[next]);
            if (i == 0 && dfs(nsp1, step + 1)) {
                return 1;
            }
            if (i == 1 && dfs(nsp2, step + 1)) {
                return 1;
            }
            swap(v[sp[i]], v[next]);
        }
    }
    return 0;
}
 
int main()
{
    int x;
    while (cin >> x, x != -1) {
        int sp[2];
        v.resize(13); v[0] = x;
        for (int i = 1; i < 13; i++) {
            cin >> v[i];
        }

        for (int i = 0, j = 0; i < 13; i++) {
            if (v[i] == 0) {
                sp[j++] = i;
            }
        }

        bool found = 0;
        constexpr int LIMIT = 20;
        for (limit = 0; limit <= LIMIT; limit++) {
            if (dfs(sp, 0)) {
                cout << limit << endl;
                found = 1;
                break;
            }
        }
        if (!found) {
            cout << "NA" << endl;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3004
final_rank: 3

code_snippet: #include <iostream>
#include <vector>
#include <cmath>

using namespace std;
 
struct P {
    int x, y;
    P(int x, int y) : x{x}, y{y} {}
};
 
int limit;
vector<int> v;

constexpr int X[] = {2, 1, 2, 3, 0, 1, 2, 3, 4, 1, 2, 3, 2};
constexpr int Y[] = {0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4};
 
int next_pos(int x, int y)
{
    for (int i = 0; i < 13; i++) {
        if (x == X[i] && y == Y[i]) {
            return i;
        }
    }        
    return -1;
}
 
int getMD()
{
    int sum = 0;
    for (int i = 0; i < 13; i++) {
        if (v[i] == 0) continue;
        sum += abs(X[i] - X[v[i]]) + abs(Y[i] - Y[v[i]]);
    }
    return sum;
}
 
constexpr int dx[] = {-1, 0, 1, 0};
constexpr int dy[] = {0, -1, 0, 1};
 
bool dfs(const int* sp, int step)
{
    int md = getMD();
    if (md == 0) return 1;
    if (md + step > limit) {
        return 0;
    }
    
    for (int i = 0; i < 2; i++) {
        int x = X[sp[i]], y = Y[sp[i]];
        for (int j = 0; j < 4; j++) {
            int nx = x + dx[j], ny = y + dy[j];
            int next = next_pos(nx, ny);
            if (next == -1) continue;
            
            const int nsp1[] = {next, sp[1]}, nsp2[] = {sp[0], next};
            
            swap(v[sp[i]], v[next]);
            if (i == 0 && dfs(nsp1, step + 1)) {
                return 1;
            }
            if (i == 1 && dfs(nsp2, step + 1)) {
                return 1;
            }
            swap(v[sp[i]], v[next]);
        }
    }
    return 0;
}
 
int main()
{
    int x;
    while (cin >> x, x != -1) {
        int sp[2];
        v.resize(13); v[0] = x;
        for (int i = 1; i < 13; i++) {
            cin >> v[i];
        }

        for (int i = 0, j = 0; i < 13; i++) {
            if (v[i] == 0) {
                sp[j++] = i;
            }
        }

        bool found = 0;
        constexpr int LIMIT = 20;
        for (limit = 0; limit <= LIMIT; limit++) {
            if (dfs(sp, 0)) {
                cout << limit << endl;
                found = 1;
                break;
            }
        }
        if (!found) {
            cout << "NA" << endl;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 2964
final_rank: 2

code_snippet: #include <iostream>
#include <vector>
 
using namespace std;
 
struct P {
    int y, x;
    P(int y, int x) : y{y}, x{x} {}
};
 
int limit;
vector<int> v;
 
P getPos(int x)
{
    if (x == 0) return P(0, 2);
    if (1 <= x && x <= 3) return P(1, x);
    if (4 <= x && x <= 8) return P(2, x - 4);
    if (9 <= x && x <= 11) return P(3, x - 8);
    return P(4, 2);
}
 
int getPos(P p)
{
    switch (p.y) {
        case 0:
            return (p.x == 2 ? 0 : -1);
        case 1:
            return (1 <= p.x && p.x <= 3 ? p.x : -1);
        case 2:
            return (0 <= p.x && p.x <= 4 ? p.x + 4 : -1); 
        case 3:
            return (1 <= p.x && p.x <= 3 ? p.x + 8 : -1);
        case 4:
            return (p.x == 2 ? 12 : -1);
    }
    return -1;
}
 
int getMD()
{
    int sum = 0;
    for (int i = 0; i < 13; i++) {
        if (v[i] == 0) continue;
        P np = getPos(i);
        P tp = getPos(v[i]);
        sum += abs(np.x - tp.x) + abs(np.y - tp.y);
    }
    return sum;
}
 
constexpr int dx[] = {-1, 0, 1, 0};
constexpr int dy[] = {0, -1, 0, 1};
 
bool dfs(int sp1, int sp2, int step)
{
    int md = getMD();
    if (md == 0) return 1;
    if (md + step > limit) {
        return 0;
    }
    P p[2] = {getPos(sp1), getPos(sp2)};
    for (int i = 0; i < 2; i++) {
        int x = p[i].x, y = p[i].y;
        for (int j = 0; j < 4; j++) {
            int nx = x + dx[j], ny = y + dy[j];
            P np(ny, nx);
            int next = getPos(np);
            if (next == -1) continue;
            if (i == 0) {
                swap(v[sp1], v[next]);
                if (dfs(next, sp2, step + 1)) {
                    return 1;
                }
                swap(v[sp1], v[next]);
            } else {
                swap(v[sp2], v[next]);
                if (dfs(sp1, next, step + 1)) {
                    return 1;
                }
                swap(v[sp2], v[next]);
            }
        }
    }
    return 0;
}
 
int main()
{
    int x;
    while (cin >> x, x != -1) {
        int sp[2];
        v.resize(13); v[0] = x;
        for (int i = 1; i < 13; i++) {
            cin >> v[i];
        }
        for (int i = 0, j = 0; i < 13; i++) {
            if (v[i] == 0) {
                sp[j++] = i;
            }
        }
        bool found = 0;
        constexpr int LIMIT = 20;
        for (limit = 0; limit <= LIMIT; limit++) {
            if (dfs(sp[0], sp[1], 0)) {
                cout << limit << endl;
                found = 1;
                break;
            }
        }
        if (!found) {
            cout << "NA" << endl;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 2988
final_rank: 4

code_snippet: #include <iostream>
#include <queue>
#include <map>
using namespace std;

unsigned long long int makeID( int (&p)[ 13 ] )
{
	unsigned long long int ret = 0;
	for( int i = 0; i < 13; ++i ){
		ret *= 13;
		ret += p[ i ];
	}
	return ret;
}

unsigned long long int slide( unsigned long long int s, int a, int b )
{
	int p[ 13 ];
	for( int i = 0; i < 13; ++i ){
		p[ 12 - i ] = s % 13;
		s /= 13;
	}
	int t = p[ a ];
	p[ a ] = p[ b ];
	p[ b ] = t;
	return makeID( p );
}

int side[][ 4 ] = {
	{ -1, -1,  2, -1 },
	{ -1,  2,  5, -1 },
	{  0,  3,  6,  1 },
	{ -1, -1,  7,  2 },
	{ -1,  5, -1, -1 },
	{  1,  6,  9,  4 },
	{  2,  7, 10,  5 },
	{  3,  8, 11,  6 },
	{ -1, -1, -1,  7 },
	{  5, 10, -1, -1,},
	{  6, 11, 12,  9 },
	{  7, -1, -1, 10 },
	{ 10, -1, -1, -1 }
};

int solve( map< unsigned long long int, int >& ans, queue< unsigned long long int >& q, int* p, map< unsigned long long int, int >* sub )
{
	int cnt = 1;
	while( cnt <= 10 ){
		int size = q.size();
		for( int i = 0; i < size; ++i ){
			unsigned long long int s = q.front();
			q.pop();
			int pos[ 2 ], a = 0;
			unsigned long long int t = s;
			for( int j = 0; j < 13; ++j ){
				int b = t % 13;
				if( b == 0 ) pos[ a++ ] = 12 - j;
				t /= 13;
			}
			for( int j = 0; j < 2; ++j ){
				int b = pos[ j ];
				for( int k = 0; k < 4; ++k ){
					int c = side[ b ][ k ];
					if( c == -1 ) continue;
					t = slide( s, b, c );
					bool e = ans.find( t ) == ans.end();
					if( sub == NULL ){
						if( e ){
							ans[ t ] = cnt;
							q.push( t );
						}
					}else{
						if( !e ){
							return ans[ t ] + cnt;
						}else if( sub->find( t ) == sub->end() ){
							(*sub)[ t ] = cnt;
							q.push( t );
						}
					}
				}
			}
		}
		++cnt;
	}
	return -1;
}

int main()
{
	map< unsigned long long int, int > ans;
	queue< unsigned long long int > q;


	int p[ 13 ];
	for( int i = 0; i < 13; ++i ){
		p[ i ] = i;
	}
	p[ 12 ] = 0;
	unsigned long long int s = makeID( p );
	ans[ s ] = 0;
	q.push( s );

	solve( ans, q, p, NULL );

	while( !q.empty() )q.pop();

	while( cin >> p[ 0 ] && p [ 0 ] != -1 ){
		for( int i = 1; i < 13; ++i ){
			cin >> p[ i ];
		}
		queue< unsigned long long int > qq;
		s = makeID( p );
		qq.push( s );
		int r;
		map< unsigned long long int, int > u;
		if( ans.find( s ) != ans.end() ){
			r = ans[ s ];
		}else{
			r = solve( ans, qq, p, &u );
		}
		if( r >= 0 ){
			cout << r << endl;
		}else{
			cout << "NA" << endl;
		}
	}

	return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 5144
final_rank: 12

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
#define MAX_N 20
#define WIDTH 100
int OK[5][5] = { {0,0,1,0,0},{0,1,1,1,0},{1,1,1,1,1},{0,1,1,1,0},{0,0,1,0,0} };
int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 };
pair<int, vector<vector<int>>> dp[MAX_N + 2][WIDTH], E[WIDTH * 10];

int score(vector<vector<int>>p) {
	int sum = 0; pair<int, int>a[12], b[12]; int CNT = 0;
	for (int i = 0; i < 25; i++) {
		if (p[i / 5][i % 5] >= 1)a[p[i / 5][i % 5]] = make_pair(i / 5, i % 5);
	}
	for (int i = 5; i < 20; i++) {
		if (OK[i / 5][i % 5] == 1) { CNT++; b[CNT] = make_pair(i / 5, i % 5); }
	}
	for (int i = 1; i <= 11; i++) { sum += abs(a[i].first - b[i].first) + abs(a[i].second - b[i].second); }
	return sum;
}
vector<vector<int>> Move(vector<vector<int>>p, int x, int y,int dir) {
	swap(p[x + dx[dir]][y + dy[dir]], p[x][y]); return p;
}
int BeemSearch(vector<vector<int>>Z) {
	vector<vector<int>>GOAL; int CNT = 0;
	for (int i = 0; i < 5; i++) { vector<int>GOAL2(5, -1); GOAL.push_back(GOAL2); }
	for (int i = 5; i < 20; i++) {
		if (OK[i / 5][i % 5] == 1) { CNT++; GOAL[i / 5][i % 5] = CNT; }
	}
	GOAL[0][2] = 0; GOAL[4][2] = 0;
	if (Z == GOAL)return 0;
	dp[0][0] = make_pair(score(Z), Z);
	for (int i = 0; i < MAX_N; i++) {
		int CNTS = 0;
		for (int j = 0; j < WIDTH; j++) {
			if (dp[i][j].second.size() == 0)continue;
			vector<vector<int>>D = dp[i][j].second;
			for (int k = 0; k < 25; k++) {
				if (D[k / 5][k % 5] != 0)continue;
				for (int l = 0; l < 4; l++) {
					int cx = (k / 5) + dx[l], cy = (k % 5) + dy[l];
					if (cx < 0 || cx >= 5 || cy < 0 || cy >= 5)continue;
					if (D[cx][cy] <= 0)continue;
					vector<vector<int>>D2 = Move(D, k / 5, k % 5, l);
					E[CNTS] = make_pair(score(D2), D2); CNTS++;
				}
			}
		}
		sort(E, E + CNTS); dp[i + 1][0] = E[0]; int CNT2 = 1;
		if (E[0].first == 0)return i + 1;
		for (int j = 1; j < CNTS; j++) {
			if (E[j - 1] != E[j]) { dp[i + 1][CNT2] = E[j]; CNT2++; }
			if (CNT2 == WIDTH)break;
		}
	}
	return -1;
}
int main() {
	while (true) {
		for (int i = 0; i < MAX_N + 2; i++) {
			for (int j = 0; j < WIDTH; j++) {
				vector<vector<int>>ZERO; dp[i][j] = make_pair(0, ZERO);
			}
		}
		for (int i = 0; i < WIDTH * 10; i++) { vector<vector<int>>ZERO; E[i] = make_pair(0, ZERO); }
		vector<vector<int>>C;
		for (int i = 0; i < 5; i++) { vector<int>C2(5, -1); C.push_back(C2); }
		cin >> C[0][2]; if (C[0][2] == -1)break;
		for (int i = 1; i < 4; i++)cin >> C[1][i];
		for (int i = 0; i < 5; i++)cin >> C[2][i];
		for (int i = 1; i < 4; i++)cin >> C[3][i]; cin >> C[4][2];
		int ret = BeemSearch(C);
		if (ret == -1)cout << "NA" << endl; else cout << ret << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 3928
final_rank: 9