Problem:
Problem G:
Rolling Dice
The north country is conquered by the great shogun-sama (which means
king). Recently many beautiful dice which were made by order of the
great shogun-sama were given to all citizens of the country. All
citizens received the beautiful dice with a tear of delight. Now they
are enthusiastically playing a game with the dice.
The game is played on grid of
h
*
w
cells that each of which has a
number, which is designed by the great shogun-sama's noble philosophy.
A player put his die on a starting cell and move it to a destination
cell with rolling the die. After rolling the die once, he takes a
penalty which is multiple of the number written on current cell and
the number printed on a bottom face of the die, because of malicious
conspiracy of an enemy country. Since the great shogun-sama strongly
wishes, it is decided that the beautiful dice are initially put so
that 1 faces top, 2 faces south, and 3 faces east. You will find that
the number initially faces north is 5, as sum of numbers on opposite
faces of a die is always 7. Needless to say, idiots those who move his
die outside the grid are punished immediately.
The great shogun-sama is pleased if some citizens can move the
beautiful dice with the least penalty when a grid and a starting cell
and a destination cell is given. Other citizens should be sent to coal
mine (which may imply labor as slaves). Write a program so that
citizens can deal with the great shogun-sama's expectations.
Input
The first line of each data set has two numbers
h
and
w
, which stands
for the number of rows and columns of the grid.
Next
h
line has
w
integers, which stands for the number printed on the
grid. Top-left corner corresponds to northwest corner.
Row number and column number of the starting cell are given in the
following line, and those of the destination cell are given in the next
line. Rows and columns are numbered 0 to
h
-1, 0 to
w
-1, respectively.
Input terminates when
h
=
w
= 0.
Output
For each dataset, output the least penalty.
Constraints
1 ≤
h
,
w
≤ 10
0 ≤ number assinged to a cell ≤ 9
the start point and the goal point are different.
Sample Input
1 2
8 8
0 0
0 1
3 3
1 2 5
2 8 3
0 1 2
0 0
2 2
3 3
1 2 5
2 8 3
0 1 2
0 0
1 2
2 2
1 2
3 4
0 0
0 1
2 3
1 2 3
4 5 6
0 0
1 2
0 0
Output for the Sample Input
24
19
17
6
21

Submitted solutions:

code_snippet: #include <iostream>
#include <queue>
#include <map>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
int dx[]={-1,1,0,0},dy[]={0,0,-1,1};
class DICE{
public:
	vector<int> dice;
	DICE(){
		dice.resize(6);
		rep(i,6)dice[i]=i+1;
	}
	// top/front/right/left/back/bottom  
	void back(){
		int to[] = {4,0,2,3,5,1};
		vector<int> tmp(6);
		rep(i,6)tmp[to[i]] = dice[i];
		dice = tmp;
	}
	void left(){
		int to[] = {3,1,0,5,4,2};
		vector<int> tmp(6);
		rep(i,6)tmp[to[i]] = dice[i];
		dice = tmp;
	}
	void rotate(){
		int to[] = {0,3,1,4,2,5};
		vector<int> tmp(6);
		rep(i,6)tmp[to[i]] = dice[i];
		dice = tmp;
	}
	void select(int n){
		if(n==0)left();
		else if(n==1)left(),left(),left();
		else if(n==2)back();
		else if(n==3)back(),back(),back();
	}
};
struct NODE{
	int cost,x,y;
	DICE dice;
	NODE(int a,int b,int c,DICE d){cost = a , x = b , y = c , dice = d;}
};
bool operator<(const NODE &a,const NODE &b){
	if(a.x != b.x)return a.x < b.x;
	if(a.y != b.y)return a.y < b.y;
	if(a.dice.dice != b.dice.dice)return a.dice.dice < b.dice.dice;
	return false;
}
bool operator>(const NODE &a,const NODE &b){
	return a.cost > b.cost;
}
int main(){
	int W,H;
	int data[10][10];
	while(cin >> H >> W , H){
		map<NODE,bool> done;
		priority_queue<NODE,vector<NODE>,greater<NODE> > Q;
		rep(i,H)rep(j,W)
			cin >> data[i][j];
		int sx,sy,gx,gy;
		cin >> sy >> sx >> gy >> gx;
		Q.push(NODE(0,sx,sy,DICE()));
		while(Q.size()){
			NODE q = Q.top(); Q.pop();
			if(done[q])continue;
			else done[q] = true;
			if(q.x == gx && q.y == gy){
				cout << q.cost << endl;
				break;
			}
			rep(i,4){
				NODE next = q;
				next.x = dx[i] + q.x;
				next.y = dy[i] + q.y;
				next.dice.select(i);
				if(next.x < 0 || next.y < 0 || next.y >= H || next.x >= W) continue;
				next.cost = q.cost + next.dice.dice[5] * data[next.y][next.x] ;
				Q.push(next);
			}
		}
	}
}
accuracy: 1
time_ms: 200
memory_kb: 3304
final_rank: 13

code_snippet: #include <iostream>
#include <queue>
#include <map>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
int dx[]={-1,1,0,0},dy[]={0,0,-1,1};
class DICE{
public:
	vector<int> dice;
	DICE(){
		dice.resize(6);
		rep(i,6)dice[i]=i+1;
	}
	// top/front/right/left/back/bottom  
	void back(){
		int to[] = {4,0,2,3,5,1};
		vector<int> tmp(6);
		rep(i,6)tmp[to[i]] = dice[i];
		dice = tmp;
	}
	void left(){
		int to[] = {3,1,0,5,4,2};
		vector<int> tmp(6);
		rep(i,6)tmp[to[i]] = dice[i];
		dice = tmp;
	}
	void rotate(){
		int to[] = {0,3,1,4,2,5};
		vector<int> tmp(6);
		rep(i,6)tmp[to[i]] = dice[i];
		dice = tmp;
	}
	void select(int n){
		if(n==0)left();
		else if(n==1)left(),left(),left();
		else if(n==2)back();
		else if(n==3)back(),back(),back();
	}
};
struct NODE{
	int cost,x,y;
	DICE dice;
	NODE(int a,int b,int c,DICE d){cost = a , x = b , y = c , dice = d;}
};
bool operator<(const NODE &a,const NODE &b){
	if(a.x != b.x)return a.x < b.x;
	if(a.y != b.y)return a.y < b.y;
	if(a.dice.dice != b.dice.dice)return a.dice.dice < b.dice.dice;
	return false;
}
bool operator>(const NODE &a,const NODE &b){
	return a.cost > b.cost;
}
int main(){
	int W,H;
	int data[10][10];
	while(cin >> H >> W , H){
		map<NODE,bool> done;
		priority_queue<NODE,vector<NODE>,greater<NODE> > Q;
		rep(i,H)rep(j,W)
			cin >> data[i][j];
		int sx,sy,gx,gy;
		cin >> sy >> sx >> gy >> gx;
		Q.push(NODE(0,sx,sy,DICE()));
		while(Q.size()){
			NODE q = Q.top(); Q.pop();
			if(done[q])continue;
			else done[q] = true;
			if(q.x == gx && q.y == gy){
				cout << q.cost << endl;
				break;
			}
			rep(i,4){
				NODE next = q;
				next.x = dx[i] + q.x;
				next.y = dy[i] + q.y;
				next.dice.select(i);
				if(next.x < 0 || next.y < 0 || next.y >= H || next.x >= W) continue;
				next.cost = q.cost + next.dice.dice[5] * data[next.y][next.x] ;
				Q.push(next);
			}
		}
	}
}
accuracy: 1
time_ms: 210
memory_kb: 3392
final_rank: 14

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
typedef long long int ll;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000001
using namespace std;

class Dice{
public:
	Dice(){
		number = new int[6];
		work = new int[6];
	};

	void roll(char dst){
		for(int i = 0; i < 6; i++) work[i] = number[i];
		switch(dst){
		case 'E':
			setNumber(work[3],work[1],work[0],work[5],work[4],work[2]);
			break;
		case 'S':
			setNumber(work[1],work[5],work[2],work[3],work[0],work[4]);
			break;
		case 'N':
			setNumber(work[4],work[0],work[2],work[3],work[5],work[1]);
			break;
		case 'W':
			setNumber(work[2],work[1],work[5],work[0],work[4],work[3]);
			break;
		}
	};

	int getBottom(){
		return number[5];
	}

	int getEast(){
		return number[2];
	}

	void setNumber(int n0,int n1,int n2,int n3,int n4,int n5){
		number[0] = n0;
		number[1] = n1;
		number[2] = n2;
		number[3] = n3;
		number[4] = n4;
		number[5] = n5;
	}

	void init(){
		setNumber(1,5,3,4,2,6);
	}

	void set(Dice arg){
		for(int i = 0; i < 6; i++){
			number[i] = arg.number[i];
		}
	}

	int* number;
	int* work;
};

int H,W,diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};

struct Info{
	Info(){
		row = col = penalty = 0;
		dice.init();
	}

	void set(int arg_row,int arg_col,int arg_penalty){
		row = arg_row;
		col = arg_col;
		penalty = arg_penalty;
	}
	int row,col,penalty;
	Dice dice;
};

bool rangeCheck(int row,int col){
	if(row >= 0 && row <= H-1 && col >= 0 && col <= W-1)return true;
	else{
		return false;
	}
}

int main(){

	int dp[10][10][7][7];
	int map[10][10],start_row,start_col,goal_row,goal_col,minimum,next_row,next_col;
	queue<Info> Q;

	while(true){
		scanf("%d %d",&H,&W);
		if(H == 0 && W == 0)break;

		for(int i = 0; i < H; i++){
			for(int k = 0; k < W; k++)scanf("%d",&map[i][k]);
		}

		scanf("%d %d",&start_row,&start_col);
		scanf("%d %d",&goal_row,&goal_col);

		for(int i = 0; i < H; i++){
			for(int k = 0; k < W; k++){
				for(int p = 1; p <= 6; p++){
					for(int q = 1; q <= 6; q++)dp[i][k][p][q] = BIG_NUM;
				}
			}
		}

		Info first;
		first.set(start_row,start_col,0);
		dp[start_row][start_col][first.dice.getBottom()][first.dice.getEast()] = 0;

		while(!Q.empty())Q.pop();
		Q.push(first);

		minimum = BIG_NUM;

		while(!Q.empty()){

			if(Q.front().row == goal_row && Q.front().col == goal_col){
				minimum = min(minimum,Q.front().penalty);
				Q.pop();
			}else if(Q.front().penalty >= minimum ||
					Q.front().penalty > dp[Q.front().row][Q.front().col][Q.front().dice.getBottom()][Q.front().dice.getEast()]){
				Q.pop();
			}else{

				for(int i = 0; i < 4; i++){
					next_row = Q.front().row + diff_row[i];
					next_col = Q.front().col + diff_col[i];

					if(rangeCheck(next_row,next_col)){
						Info next;
						next.set(next_row,next_col,Q.front().penalty);
						next.dice.set(Q.front().dice);
						switch(i){
						case 0:
							next.dice.roll('N');
							break;
						case 1:
							next.dice.roll('W');
							break;
						case 2:
							next.dice.roll('E');
							break;
						case 3:
							next.dice.roll('S');
							break;
						}

						if(dp[next_row][next_col][next.dice.getBottom()][next.dice.getEast()] > dp[Q.front().row][Q.front().col][Q.front().dice.getBottom()][Q.front().dice.getEast()]+
								map[next_row][next_col]*next.dice.getBottom()){
							dp[next_row][next_col][next.dice.getBottom()][next.dice.getEast()] =
									dp[Q.front().row][Q.front().col][Q.front().dice.getBottom()][Q.front().dice.getEast()]+map[next_row][next_col]*next.dice.getBottom();
							next.penalty += map[next_row][next_col]*next.dice.getBottom();
							Q.push(next);
						}
					}
				}
				Q.pop();
			}
		}

		printf("%d\n",minimum);
	}

	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 50224
final_rank: 19

code_snippet: #include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<cstdio>
#include<sstream>
#include<iomanip>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define mp make_pair
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
typedef pair<int,int> pii;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef pair<int,pii> pip;
typedef vector<pip>vip;
const double PI=acos(-1);
const double EPS=1e-8;
const int inf=1e8;
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
int rol[4][4]={
	{4,5,2,0},
	{1,0,3,5},
	{0,2,5,4},
	{5,3,0,1}
};
vi a;
void roll(int b){
	int tmp=a[2+rol[b][0]];
	rep(i,3)a[2+rol[b][i]]=a[2+rol[b][i+1]];
	a[2+rol[b][3]]=tmp;
}
int main(){
	int n,m;
	while(cin>>n>>m,n+m){
		vvi in(n,vi(m));
		rep(i,n)rep(j,m)cin>>in[i][j];
		int sx,sy,gx,gy;
		cin>>sx>>sy>>gx>>gy;
		vi q(8);
		q[0]=sx;q[1]=sy;q[2]=1;q[3]=2;
		q[4]=3;q[5]=5;q[6]=4;q[7]=6;
		int ma[11][11][666];
		rep(i,11)rep(j,11)rep(k,666)ma[i][j][k]=inf;
		ma[sx][sy][123]=0;
		int out=inf;
		priority_queue<pair<int,vi> >que;
		que.push(pair<int,vi>(0,q));
		while(!que.empty()){
			vi w=que.top().second;
			int t=-que.top().first;
			que.pop();
			if(ma[w[0]][w[1]][w[2]*100+w[3]*10+w[4]]<t)continue;
			rep(i,4){
				a=w;
				a[0]+=dx[i];
				a[1]+=dy[i];
				if(a[0]<0||a[1]<0||a[0]>=n||a[1]>=m)continue;
				roll(i);
				int cost=t+a[7]*in[a[0]][a[1]];
				if(ma[a[0]][a[1]][a[2]*100+a[3]*10+a[4]]>cost){
					ma[a[0]][a[1]][a[2]*100+a[3]*10+a[4]]=cost;
					que.push(pair<int,vi>(-cost,a));
					if(a[0]==gx&&a[1]==gy)out=min(out,cost);
				}
			}
		}
		cout<<out<<endl;
	}
}
accuracy: 1
time_ms: 60
memory_kb: 3388
final_rank: 8

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class t>
using table = vector<vector<t>>;
const ld eps = 1e-9;

enum R_Way {
	R_Left,
	R_Front,
	R_Right,
	R_Back,

	R_Dummy,
};
struct Dice {
	int tp;
	int bo;
	int no;
	int so;
	int ea;
	int we;
	Dice(int tp_, int bo_, int no_, int so_, int ea_, int we_) :
		tp(tp_), bo(bo_), no(no_), so(so_), ea(ea_), we(we_) {

	}
	Dice(vector<int>pips_) {

	}

	Dice() {
		tp = 1;
		bo = 6;
		no = 5;
		so = 2;
		ea = 3;
		we = 4;
	}

	int rotate(const R_Way way) {
		switch (way) {
		case R_Right: {
			int c = tp;
			tp = we;
			we = bo;
			bo = ea;
			ea = c;
		}
					  break;
		case R_Back: {
			int c = tp;
			tp = so;
			so = bo;
			bo = no;
			no = c;
		}
					 break;
		case R_Left: {
			int c = tp;
			tp = ea;
			ea = bo;
			bo = we;
			we = c;
		}
					 break;
		case R_Front: {
			int c = tp;
			tp = no;
			no = bo;
			bo = so;
			so = c;
		}
					  break;
		default:
			assert(false);
		}
		return tp;
	}
	int rotate(const int way) {
		return rotate(static_cast<R_Way>(way));
	}
	void spin(const int  clockwise) {
		if (!clockwise) {

			rotate(R_Way::R_Left);
			rotate(R_Way::R_Back);
			rotate(R_Way::R_Right);
		}
		else {

			rotate(R_Way::R_Left);
			rotate(R_Way::R_Front);
			rotate(R_Way::R_Right);
		}
	}
	int hash()const {
		return tp + we * 6 + no * 36;
	}
};
int geteast(int top, int south) {
	map<pair<int, int>, int>mp;
	mp[make_pair(1, 2)] = 3;
	mp[make_pair(1, 3)] = 5;
	mp[make_pair(2, 3)] = 1;
	mp[make_pair(2, 4)] = 6;
	bool rev = false;
	if (top >= 4) {
		rev = !rev; top = 7 - top;
	}
	if (south >= 4) {
		rev = !rev; south = 7 - south;
	}
	if (top > south) {
		rev = !rev; swap(top, south);
	}
	return mp[make_pair(top, south)];
}

int gettop(int south, int east) {
	return geteast(south, east);
}
int getsouth(int east, int top) {
	return 7 - geteast(top, east);
}
bool operator==(const Dice&l, const Dice&r) {
	return l.hash() == r.hash();
}

int H, W;
bool check(const int y, const int x) {
	return y >= 0 && y < H&&x >= 0 && x < W;
}
struct aa {
	int x;
	int y;
	int tp;
	int bo;
	int no;
	int so;
	int ea;
	int we;
	int hash;
	int time;
};
class Compare {
public:
	bool operator()(const aa&l, const aa&r) {
		return l.time> r.time;
	}
};	//aa?????????????????¶

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

int memo[101][101][1000];
int main() {
	map<int, int>mp;
	int num = 0;
	while (1) {
		for (int i = 0; i < 100; ++i) {
			for (int j = 0; j < 100; ++j) {
				for (int k = 0; k < 1000; ++k) {
					memo[i][j][k] = 1e8;
				}
			}
		}
		cin >> H >> W;
		if (!H)break;
		vector<vector<int>>field(H, vector<int>(W));
		for (int i = 0; i < H; ++i) {
			for (int j = 0; j < W; ++j) {
				cin >> field[i][j];
			}
		}
		int sx, sy, gx, gy; cin >> sy >> sx >> gy >> gx;
		

		priority_queue<aa, vector<aa>, Compare>que;
		Dice ini_di;
		que.push(aa{ sx,sy,ini_di.tp,ini_di.bo,ini_di.no,ini_di.so,ini_di.ea,ini_di.we,ini_di.hash(),0 });
		int ans = -1;
		while (!que.empty()) {
			aa atop(que.top());
			que.pop(); if (atop.x == gx&&atop.y == gy) {
				ans = atop.time;
				break;
			}
			for (int way = 0; way < 4; ++way) {
				const int nextx = atop.x + dx[way];
				const int nexty = atop.y + dy[way];
				
				Dice di = Dice(atop.tp, atop.bo, atop.no, atop.so, atop.ea, atop.we);
				if (check(nexty, nextx)) {
					di.rotate(way);
					const int nexttime=  atop.time + di.bo*field[nexty][nextx];
					if (mp.find(di.hash()) == mp.end()) {
						mp[di.hash()] = num++;
					}
					if (memo[nextx][nexty][mp[di.hash()]]>nexttime) {
						memo[nextx][nexty][mp[di.hash()]] = nexttime;
						que.push(aa{ nextx,nexty,di.tp,di.bo,di.no,di.so,di.ea,di.we,di.hash(),nexttime });
					}
				}
				else {
					continue;
				}
			}
		}
		cout << ans << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 900
memory_kb: 42628
final_rank: 20

code_snippet: #include <bits/stdc++.h>
 
using namespace std;
 
#define MAX_H 10
#define MAX_W 10
 
struct Dice{
    int tmp,d[6];
    Dice(){
	for(int i = 0 ; i < 6 ; i++){
	    d[i] = i;
	}
    }
    void rollN(){
	tmp = d[0];
	d[0] = d[1];
	d[1] = d[5];
	d[5] = d[4];
	d[4] = tmp;
    }
    void rollE(){
	tmp = d[0];
	d[0] = d[3];
	d[3] = d[5];
	d[5] = d[2];
	d[2] = tmp;
    }
    void rollS(){
	tmp = d[0];
	d[0] = d[4];
	d[4] = d[5];
	d[5] = d[1];
	d[1] = tmp;
    }
    void rollW(){
	tmp = d[0];
	d[0] = d[2];
	d[2] = d[5];
	d[5] = d[3];
	d[3] = tmp;
    }
};
 
struct State{
    int cost,x,y;
    Dice d;
    bool operator < (const State &s)const{
	return cost > s.cost;
    }
};
 
int main(){
    int H,W;
    while(cin >> H >> W, H){
	int field[MAX_H][MAX_W];
	int sx,sy,gx,gy;
	for(int i = 0 ; i < H ; i++){
	    for(int j = 0 ; j < W ; j++){
		cin >> field[i][j];
	    }
	}
	cin >> sy >> sx >> gy >> gx;
	int cost[MAX_H][MAX_W][6][6][6];
	for(int i = 0 ; i < H ; i++){
	    for(int j = 0 ; j < W ; j++){
		for(int k = 0 ; k < 6 ; k++){
		    for(int l = 0 ; l < 6 ; l++){
			for(int m = 0 ; m < 6 ; m++){
			    cost[i][j][k][l][m] = 1e9;
			}
		    }
		}
	    }
	}
	Dice die;
	cost[sy][sx][die.d[0]][die.d[1]][die.d[2]] = 0;
	priority_queue<State> Q;
	Q.push((State){0,sx,sy,die});
	const int dx[] = {-1,0,1,0};
	const int dy[] = {0,-1,0,1};
	while(!Q.empty()){
	    State s = Q.top(); Q.pop();
	    int x = s.x, y = s.y;
	    int ncost = cost[y][x][s.d.d[0]][s.d.d[1]][s.d.d[2]];
	    if(ncost < s.cost){ continue; }
	    if(x == gx && y == gy){
		cout << s.cost << endl;
		break;
	    }
	    for(int i = 0 ; i < 4 ; i++){
		int nx = x + dx[i], ny = y + dy[i];
		Dice d = s.d;
		if(0 > nx || nx >= W || 0 > ny || ny >= H){
		    continue;
		}
		switch(i){
		case 0:
		    d.rollW();
		    break;
		case 1:
		    d.rollN();
		    break;
		case 2:
		    d.rollE();
		    break;
		case 3:
		    d.rollS();
		    break;
		}
		int p = (d.d[5]+1)*field[ny][nx];
		if(s.cost + p < cost[ny][nx][d.d[0]][d.d[1]][d.d[2]]){
		    cost[ny][nx][d.d[0]][d.d[1]][d.d[2]] = s.cost + p;
		    Q.push((State){cost[ny][nx][d.d[0]][d.d[1]][d.d[2]],nx,ny,d});
		}
	    }
	}
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3204
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <iomanip>
#include <functional>
#include <queue>
using namespace std;

int field[10][10];

typedef long long W;

const W INF = 1LL << 50;

struct edge {
	int to;
	W cost;
};
typedef pair<W, int> P;
typedef vector<vector <edge > > Graph;

void dijkstra(int s, const Graph& G, vector<W>& d) {
	priority_queue< P, vector<P>, greater<P> > que;
	fill(d.begin(), d.end(), INF);
	d[s] = 0;
	que.push(P(0, s));
	while(!que.empty()) {
		P p = que.top();
		que.pop();
		int v = p.second;
		if(d[v] < p.first) continue;
		for(int i = 0; i < G[v].size(); i++) {
			edge e = G[v][i];
			if(d[e.to] > d[v] + e.cost) {
				d[e.to] = d[v] + e.cost;
				que.push(P(d[e.to], e.to));
			}
		}
	}
}

int toV(int x, int y, int a, int b, int c) {
	return x * 10 * 7 * 7 * 7 + y * 7 * 7 * 7 + a * 7 * 7 + b * 7 + c;
}

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

void rot(int k, int a, int b, int c, int& na, int& nb, int& nc) {
	if(k == 0) {
		na = 7 - b;
		nb = a;
		nc = c;
	}
	if(k == 1) {
		na = a;
		nb = 7 - c;
		nc = b;
	}
	if(k == 2) {
		na = b;
		nb = 7 - a;
		nc = c;
	}
	if(k == 3) {
		na = a;
		nb = c;
		nc = 7 - b;
	}
}

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	int h, w, sx, sy, gx, gy;
	while(cin >> h >> w, h) {
		for(int y = 0; y < h; y++) {
			for(int x = 0; x < w; x++) {
				cin >> field[y][x];
			}
		}

		cin >> sy >> sx >> gy >> gx;

		Graph G(10 * 10 * 7 * 7 * 7);
		vector<W> d(10 * 10 * 7 * 7 * 7);

		for(int y = 0; y < h; y++) {
			for(int x = 0; x < w; x++) {
				for(int k = 0; k < 4; k++) {
					int nx = x + dx[k], ny = y + dy[k];
					if(nx < 0 || w <= nx || ny < 0 || h <= ny) continue;
					for(int a = 1; a <= 6; a++) {
						for(int b = 1; b <= 6; b++) {
							for(int c = 1; c <= 6; c++) {
								int v1 = toV(x, y, a, b, c);
								int na, nb, nc;
								rot(k, a, b, c, na, nb, nc);
								int v2 = toV(nx, ny, na, nb, nc);
								G[v1].push_back(edge{ v2, field[ny][nx] * (7 - nb) });
							}
						}
					}
				}
			}
		}

		dijkstra(toV(sx, sy, 2, 1, 3), G, d);
		W ans = INF;
		for(int a = 1; a <= 6; a++) {
			for(int b = 1; b <= 6; b++) {
				for(int c = 1; c <= 6; c++) {
					ans = min(ans, d[toV(gx, gy, a, b, c)]);
				}
			}
		}
		cout << ans << endl;
	}
}
accuracy: 1
time_ms: 320
memory_kb: 5484
final_rank: 15

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

typedef tuple<int,int,int,int,int,int> T;//<cost,A,B,C,y,x>
#define INF 1e8

int main(){
    int h,w;
    int map[10][10];//[y][x]
    int minimum[6][6][6][10][10];//[テ、ツクツ甘ゥツ敖「テ」ツ?ョテァツ崢ョ][テ・ツ債療・ツ青妥」ツ?江[テヲツ敖アテ・ツ青妥」ツ?江[][y][x]
    priority_queue<T,vector<T>,greater<T>> que;
    while(cin>>h>>w,h){
        for(int i=0;i<h;i++){
            for(int j=0;j<w;j++){
                cin>>map[i][j];
            }
        }
        int start_y,start_x,end_y,end_x;
        cin>>start_y>>start_x>>end_y>>end_x;
        while(!que.empty())que.pop();
        que.push(T(0,1,2,3,start_y,start_x));
        fill(minimum[0][0][0][0],minimum[6][0][0][0],INF);
        while(!que.empty()){
            T t = que.top(); que.pop();
            int cost=get<0>(t), A=get<1>(t),B=get<2>(t),C=get<3>(t), y=get<4>(t), x=get<5>(t);
            if(cost>minimum[A-1][B-1][C-1][y][x]) continue;
            int penalty;
            //テ・ツ個?
            if(y){
                int newA=B,newB=7-A,newC=C;
                penalty=cost+(7-newA)*map[y-1][x];
                if(penalty<minimum[newA-1][newB-1][newC-1][y-1][x]){
                    minimum[newA-1][newB-1][newC-1][y-1][x]=penalty;
                    que.emplace(penalty,newA,newB,newC,y-1,x);
                }
            }
            //テ・ツ債?
            if(y!=h-1){
                int newA=7-B,newB=A,newC=C;
                penalty=cost+(7-newA)*map[y+1][x];
                if(penalty<minimum[newA-1][newB-1][newC-1][y+1][x]){
                    minimum[newA-1][newB-1][newC-1][y+1][x]=penalty;
                    que.emplace(penalty,newA,newB,newC,y+1,x);
                }
            }
            //テヲツ敖ア
            if(x!=w-1){
                int newA=7-C,newB=B,newC=A;
                penalty=cost+(7-newA)*map[y][x+1];
                if(penalty<minimum[newA-1][newB-1][newC-1][y][x+1]){
                    minimum[newA-1][newB-1][newC-1][y][x+1]=penalty;
                    que.emplace(penalty,newA,newB,newC,y,x+1);
                }
            }
            //ティツ・ツソ
            if(x){
                int newA=C,newB=B,newC=7-A;
                penalty=cost+(7-newA)*map[y][x-1];
                if(penalty<minimum[newA-1][newB-1][newC-1][y][x-1]){
                    minimum[newA-1][newB-1][newC-1][y][x-1]=penalty;
                    que.emplace(penalty,newA,newB,newC,y,x-1);
                }
            }
        }
        int ans=INF;
        for(int i=0;i<6;i++)for(int j=0;j<6;j++)for(int k=0;k<6;k++)ans=min(ans,minimum[i][j][k][end_y][end_x]);
        cout<<ans<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3096
final_rank: 5

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

using namespace std;

#define MAX_H 10
#define MAX_W 10

struct Dice{
  int tmp,d[6];
  Dice(){
    for(int i = 0 ; i < 6 ; i++){
      d[i] = i;
    }
  }
  void rollN(){
    tmp = d[0];
    d[0] = d[1];
    d[1] = d[5];
    d[5] = d[4];
    d[4] = tmp;
  }
  void rollE(){
    tmp = d[0];
    d[0] = d[3];
    d[3] = d[5];
    d[5] = d[2];
    d[2] = tmp;
  }
  void rollS(){
    tmp = d[0];
    d[0] = d[4];
    d[4] = d[5];
    d[5] = d[1];
    d[1] = tmp;
  }
  void rollW(){
    tmp = d[0];
    d[0] = d[2];
    d[2] = d[5];
    d[5] = d[3];
    d[3] = tmp;
  }
};

struct State{
  int cost,x,y;
  Dice d;
  bool operator < (const State &s)const{
    return cost > s.cost;
  }
};

int main(){
  int H,W;
  while(cin >> H >> W, H){
    int field[MAX_H][MAX_W];
    int sx,sy,gx,gy;
    for(int i = 0 ; i < H ; i++){
      for(int j = 0 ; j < W ; j++){
        cin >> field[i][j];
      }
    }
    cin >> sy >> sx >> gy >> gx;
    int cost[MAX_H][MAX_W][6][6][6];
    for(int i = 0 ; i < H ; i++){
      for(int j = 0 ; j < W ; j++){
        for(int k = 0 ; k < 6 ; k++){
          for(int l = 0 ; l < 6 ; l++){
            for(int m = 0 ; m < 6 ; m++){
              cost[i][j][k][l][m] = 1e9;
            }
          }
        }
      }
    }
    Dice die;
    cost[sy][sx][die.d[0]][die.d[1]][die.d[2]] = 0;
    priority_queue<State> Q;
    Q.push((State){0,sx,sy,die});
    const int dx[] = {-1,0,1,0};
    const int dy[] = {0,-1,0,1};
    while(!Q.empty()){
      State s = Q.top(); Q.pop();
      int x = s.x, y = s.y;
      int ncost = cost[y][x][s.d.d[0]][s.d.d[1]][s.d.d[2]];
      if(ncost < s.cost){ continue; }
      if(x == gx && y == gy){
        cout << s.cost << endl;
        break;
      }
      for(int i = 0 ; i < 4 ; i++){
        int nx = x + dx[i], ny = y + dy[i];
        Dice d = s.d;
        if(0 > nx || nx >= W || 0 > ny || ny >= H){
          continue;
        }
        switch(i){
        case 0:
          d.rollW();
          break;
        case 1:
          d.rollN();
          break;
        case 2:
          d.rollE();
          break;
        case 3:
          d.rollS();
          break;
        }
        int p = (d.d[5]+1)*field[ny][nx];
        if(s.cost + p < cost[ny][nx][d.d[0]][d.d[1]][d.d[2]]){
          cost[ny][nx][d.d[0]][d.d[1]][d.d[2]] = s.cost + p;
          Q.push((State){cost[ny][nx][d.d[0]][d.d[1]][d.d[2]],nx,ny,d});
        }
      }
    }
  }
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 1320
final_rank: 2

code_snippet: #include<iostream>
#include<queue>
#include<cstring>
using namespace std;
struct state{
  int y,x,a,b,c,d,e,f,cost;
  bool operator < (const state&p)const{
    return cost > p.cost;
  }
};

int h,w;
int t[10][10];

int d[10][10][6][6][6][6][6][6];

void solve(){
  int ay,ax,by,bx;
  cin>>ay>>ax>>by>>bx;
  //memset(d,sizeof(d),0);  
  for(int i=0;i<10;i++)
    for(int j=0;j<10;j++)
      for(int k=0;k<6;k++)
    for(int l=0;l<6;l++)
      for(int m=0;m<6;m++)
        for(int n=0;n<6;n++)
          for(int o=0;o<6;o++)
        for(int p=0;p<6;p++)
          d[i][j][k][l][m][n][o][p]=0;
  d[ay][ax][0][1][2][3][4][5]=1;
  priority_queue< state > Q;
  Q.push((state){ay,ax,0,1,2,3,4,5,1});
  while(!Q.empty()){
    state s=Q.top();Q.pop();
    if(s.cost>d[s.y][s.x][s.a][s.b][s.c][s.d][s.e][s.f])continue;
    if(s.y==by&&s.x==bx){cout<<s.cost-1<<endl;return;}
    if(s.y>0){
      int* k=&d[s.y-1][s.x][s.b][s.f][s.c][s.d][s.a][s.e];
      int ncost=s.cost+(s.e+1)*t[s.y-1][s.x];
      if( *k==0 || ncost < *k){
	*k=ncost;
	Q.push((state){s.y-1,s.x,s.b,s.f,s.c,s.d,s.a,s.e,ncost});
      }
    }
    if(s.y+1<h){
      int* k=&d[s.y+1][s.x][s.e][s.a][s.c][s.d][s.f][s.b];
      int ncost=s.cost+(s.b+1)*t[s.y+1][s.x];
      if( *k==0 || ncost < *k){
	*k=ncost;
	Q.push((state){s.y+1,s.x,s.e,s.a,s.c,s.d,s.f,s.b,ncost});
      }
    }
    if(s.x>0){
      int* k=&d[s.y][s.x-1][s.c][s.b][s.f][s.a][s.e][s.d];
      int ncost=s.cost+(s.d+1)*t[s.y][s.x-1];
      if( *k==0 || ncost < *k){
	*k=ncost;
	Q.push((state){s.y,s.x-1,s.c,s.b,s.f,s.a,s.e,s.d,ncost});
      }  
    }
    if(s.x+1<w){
      int* k=&d[s.y][s.x+1][s.d][s.b][s.a][s.f][s.e][s.c];
      int ncost=s.cost+(s.c+1)*t[s.y][s.x+1];
      if( *k==0 || ncost < *k){
	*k=ncost;
	Q.push((state){s.y,s.x+1,s.d,s.b,s.a,s.f,s.e,s.c,ncost});
      }  
    }
  }
  cout<<"NA"<<endl;
}

int main(){
  while(1){
    cin>>h>>w;
    if(h==0&&w==0)break;
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++)
	cin>>t[i][j];
    solve();
  }
  return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 19480
final_rank: 17

code_snippet: #include <iostream>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <utility>
#include <iomanip>
#include <algorithm>
#include <functional>
using namespace std;

typedef long long ll;
typedef vector<int> vint;
typedef vector<long long> vll;
typedef pair<int,int> pint;
typedef pair<long long, long long> pll;

#define MP make_pair
#define PB push_back
#define ALL(s) (s).begin(),(s).end()
#define EACH(i, s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P) 
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P) 
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P) 
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P) 
{ EACH(it, P) { s << "<" << it->first << "->" << it->second << "> "; } return s; }


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

#define roll_swap(x, a, b, c, d) swap(x.a, x.b), swap(x.b, x.c), swap(x.c, x.d);
struct Dice {
    int top, front, right, left, back, bottom;
    
    Dice(int to = 1, int fr = 2, int ri = 3, int le = 4, int ba = 5, int bo = 6) 
    : top(to), front(fr), right(ri), left(le), back(ba), bottom(bo) { }
    void roll_right() { roll_swap((*this), top, left, bottom, right); }
    void roll_left() { roll_swap((*this), top, right, bottom, left); }
    void roll_front() { roll_swap((*this), top, back, bottom, front); }
    void roll_back() { roll_swap((*this), top, front, bottom, back); }
    void roll_cw() { roll_swap((*this), back, left, front, right); }
    void roll_ccw() { roll_swap((*this), back, right, front, left); }
    void roll(int dir) {
        if (dir == 0) (*this).roll_front();
        if (dir == 1) (*this).roll_right();
        if (dir == 2) (*this).roll_back();
        if (dir == 3) (*this).roll_left();
    }
    friend bool operator < (const Dice &d1, const Dice &d2) {
        int vd1[] = {d1.top, d1.front, d1.right, d1.left, d1.back, d1.bottom};
        int vd2[] = {d2.top, d2.front, d2.right, d2.left, d2.back, d2.bottom};
        return vector<int>(vd1, vd1 + 6) < vector<int>(vd2, vd2 + 6);
    }
    friend ostream& operator << (ostream& s, const Dice& d) { 
        return s << '<' << d.top << ',' << d.front << ',' << d.right << '>'; 
    }
};

vector<Dice> all_rotate() {
    vector<Dice> res(24);
    Dice d;
    for (int i = 0; i < 6; ++i) {
        for (int j = 0; j < 4; j++) {
            res[i * 4 + j] = d;
            d.roll_cw();
        }
        if (i & 1) d.roll_front();
        else d.roll_right();
    }
    return res;    
}

const int INF = 1<<29;

int n, m;
int fi[15][15];
int sx, sy, tx, ty;

int main() {
    //freopen( "/Users/macuser/Dropbox/Contest/input.in", "r", stdin );
    
    vector<Dice> vd = all_rotate();
    map<Dice,int> ma;
    for (int i = 0; i < vd.size(); ++i) ma[vd[i]] = i;
    
//    COUT(vd);
//    COUT(ma);
    
    while (cin >> n >> m) {
        if (n == 0) break;
        for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) cin >> fi[i][j];
        cin >> sx >> sy >> tx >> ty;
        
        int dp[15][15][31];
        for (int i = 0; i < 15; ++i) for (int j = 0; j < 15; ++j) for (int k = 0; k < 31; ++k) dp[i][j][k] = INF;
        dp[sx][sy][0] = 0;
        priority_queue< pair<int,pair<pint,int> >, vector<pair<int,pair<pint,int> > >, greater<pair<int,pair<pint,int> > > > que;
        que.push( MP(0, MP(pint(sx,sy), 0)) );
        while (!que.empty()) {
            //cout << que.top() << endl;
            
            int dist = que.top().first;
            int x = que.top().second.first.first;
            int y = que.top().second.first.second;
            int id = que.top().second.second;
            Dice d = vd[id];
            que.pop();
            
            if (dist > dp[x][y][id]) continue;
            
            for (int i = 0; i < 4; ++i) {
                int nx = x + dx[i], ny = y + dy[i];
                if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
                Dice nd = d;
                nd.roll(i);
                int nid = ma[nd];
                
                int add = nd.bottom * fi[nx][ny];
                int ndist = dist + add;
                if (chmin(dp[nx][ny][nid], ndist)) {
                    que.push( MP(ndist, MP(pint(nx,ny),nid)) );
                }
            }
        }
        
        int Min = INF;
        for (int i = 0; i < 24; ++i) chmin(Min, dp[tx][ty][i]);
        
        cout << Min << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 1244
final_rank: 10

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

#define dump(...) cout<<'L'<<__LINE__<<": "<<#__VA_ARGS__<<'='<<(__VA_ARGS__)<<endl
template<typename Tuple>
void print_tuple(ostream&,const Tuple&){}
template<typename Car,typename... Cdr,typename Tuple>
void print_tuple(ostream& os,const Tuple& t){
	print_tuple<Cdr...>(os,t);
	os<<(sizeof...(Cdr)?",":"")<<get<sizeof...(Cdr)>(t);
}
template<typename... Args>
ostream& operator<<(ostream& os,const tuple<Args...>& t){
	os<<'(';
	print_tuple<Args...>(os,t);
	return os<<')';
}

struct Die{
	array<int,6> faces;
	Die(){
		faces[0]=2; faces[1]=5;
		faces[2]=3; faces[3]=4;
		faces[4]=1; faces[5]=6;
	}
	void Rotate(int a,int b,int c,int d){
		swap(faces[a],faces[b]);
		swap(faces[b],faces[c]);
		swap(faces[c],faces[d]);
	}
	void TurnU(){Rotate(4,0,5,1);}
	void TurnD(){Rotate(4,1,5,0);}
	void TurnL(){Rotate(4,2,5,3);}
	void TurnR(){Rotate(4,3,5,2);}
};
bool operator<(const Die& a,const Die& b){
	return lexicographical_compare(begin(a.faces),end(a.faces),begin(b.faces),end(b.faces));
}
bool operator>(const Die& a,const Die& b){
	return lexicographical_compare(begin(b.faces),end(b.faces),begin(a.faces),end(a.faces));
}

template<typename Functor>
struct functor_traits{
	template<typename C,typename Ret,typename Arg,typename... Args>
	static Arg helper(Ret(C::*)(Arg,Args...));
	template<typename C,typename Ret,typename Arg,typename... Args>
	static Arg helper(Ret(C::*)(Arg,Args...)const);
	typedef decltype(helper(&Functor::operator())) first_argument_type;
};
template<typename Compare,typename T=typename functor_traits<Compare>::first_argument_type>
priority_queue<T,vector<T>,Compare> make_priority_queue(Compare comp){
	return priority_queue<T,vector<T>,Compare>(move(comp));
}

int main()
{
	for(int h,w;cin>>h>>w && h|w;){
		vector<vector<int>> grid(h,vector<int>(w));
		for(int i=0;i<h;i++)
			for(int j=0;j<w;j++)
				cin>>grid[i][j];
		int si,sj,gi,gj; cin>>si>>sj>>gi>>gj;
		
		auto pq=make_priority_queue([](tuple<Die,int,int,int> a,tuple<Die,int,int,int> b){
			return get<3>(a)>get<3>(b);
		});
		pq.emplace(Die(),si,sj,0);
		set<tuple<Die,int,int>> vis;
		while(pq.size()){
			Die d; int i,j,c; tie(d,i,j,c)=pq.top(); pq.pop();
			if(vis.count(make_tuple(d,i,j))) continue;
			vis.insert(make_tuple(d,i,j));
			if(i==gi && j==gj){
				cout<<c<<endl;
				break;
			}
			function<void(Die&)> turns[]={&Die::TurnU,&Die::TurnD,&Die::TurnL,&Die::TurnR};
			for(int k=0;k<4;k++){
				int ni=i+"\xff\x1\0\0"[k],nj=j+"\0\0\xff\x1"[k];
				if(0<=ni && ni<h && 0<=nj && nj<w){
					Die t=d;
					turns[k](t);
					pq.emplace(t,ni,nj,c+t.faces[5]*grid[ni][nj]);
				}
			}
		}
	}
}
accuracy: 1
time_ms: 110
memory_kb: 1356
final_rank: 9

code_snippet: #include<stdio.h>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
int ijk[11][11][800];
int v[11][11][800];
int c[12][12];
struct wolf{
	int t[6];
	wolf(){
		for(int i=0;i<6;i++)t[i]=i;
	}
};
inline bool operator<(const wolf&a,const wolf&b){
	for(int i=0;i<6;i++)if(a.t[i]!=b.t[i])return a.t[i]<b.t[i];
	return false;
}
map<wolf,int>m;
vector<wolf>rev;
void rN(wolf &a){int tmp=a.t[0];a.t[0]=a.t[1];a.t[1]=a.t[5];a.t[5]=a.t[4];a.t[4]=tmp;}
void rS(wolf &a){int tmp=a.t[0];a.t[0]=a.t[4];a.t[4]=a.t[5];a.t[5]=a.t[1];a.t[1]=tmp;}
void rE(wolf &a){int tmp=a.t[0];a.t[0]=a.t[3];a.t[3]=a.t[5];a.t[5]=a.t[2];a.t[2]=tmp;}
void rW(wolf &a){int tmp=a.t[0];a.t[0]=a.t[2];a.t[2]=a.t[5];a.t[5]=a.t[3];a.t[3]=tmp;}
int main(){
	int a,b;
	wolf test;
	int sz=0;
	do{
		rev.push_back(test);
		m[test]=sz++;
	}while(next_permutation(test.t,test.t+6));
	while(scanf("%d%d",&a,&b),a){
		for(int i=0;i<a;i++)for(int j=0;j<b;j++)scanf("%d",&c[i][j]);
		for(int i=0;i<a;i++)for(int j=0;j<b;j++)for(int k=0;k<sz;k++){
			ijk[i][j][k]=999999999;v[i][j][k]=0;
		}
		int sr,sc,gr,gc;scanf("%d%d%d%d",&sr,&sc,&gr,&gc);
		ijk[sr][sc][0]=0;
		priority_queue<pair<pair<int,int>,pair<int,int> > >Q;
		Q.push(make_pair(make_pair(0,0),make_pair(sr,sc)));
		while(Q.size()){
			int cost=-Q.top().first.first;
			int st=Q.top().first.second;
			wolf now=rev[st];
			int row=Q.top().second.first;
			int col=Q.top().second.second;
			Q.pop();
			if(v[row][col][st])continue;
			v[row][col][st]=1;
			int to;
			rN(now);to=m[now];
			if(row&&!v[row-1][col][to]&&ijk[row-1][col][to]>cost+(now.t[5]+1)*c[row-1][col]){
				ijk[row-1][col][to]=cost+(now.t[5]+1)*c[row-1][col];
				Q.push(make_pair(make_pair(-ijk[row-1][col][to],to),make_pair(row-1,col)));
			}rS(now);
			rS(now);to=m[now];
			if(row<a-1&&!v[row+1][col][to]&&ijk[row+1][col][to]>cost+(now.t[5]+1)*c[row+1][col]){
				ijk[row+1][col][to]=cost+(now.t[5]+1)*c[row+1][col];
				Q.push(make_pair(make_pair(-ijk[row+1][col][to],to),make_pair(row+1,col)));
			}rN(now);
			rW(now);to=m[now];
			if(col&&!v[row][col-1][to]&&ijk[row][col-1][to]>cost+(now.t[5]+1)*c[row][col-1]){
				ijk[row][col-1][to]=cost+(now.t[5]+1)*c[row][col-1];
				Q.push(make_pair(make_pair(-ijk[row][col-1][to],to),make_pair(row,col-1)));
			}rE(now);
			rE(now);to=m[now];
			if(col<b-1&&!v[row][col+1][to]&&ijk[row][col+1][to]>cost+(now.t[5]+1)*c[row][col+1]){
				ijk[row][col+1][to]=cost+(now.t[5]+1)*c[row][col+1];
				Q.push(make_pair(make_pair(-ijk[row][col+1][to],to),make_pair(row,col+1)));
			}rW(now);
		}
		int ret=99999999;
		for(int i=0;i<sz;i++)ret=min(ret,ijk[gr][gc][i]);
		printf("%d\n",ret);
	}
}
accuracy: 1
time_ms: 40
memory_kb: 1812
final_rank: 7

code_snippet: #include<iostream>
#include<queue>
#include<cstring>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)

typedef vector<int> Dice;
enum {TOP, FRONT, RIGHT, LEFT, BACK, BOTTOM};
#define rotate_swap(x, a, b, c, d) swap(x[a], x[b]); swap(x[b], x[c]); swap(x[c], x[d]);

void rotate_r(Dice &dice) {rotate_swap(dice, TOP, LEFT, BOTTOM, RIGHT);}
void rotate_l(Dice &dice) {rotate_swap(dice, TOP, RIGHT, BOTTOM, LEFT);}
void rotate_f(Dice &dice) {rotate_swap(dice, TOP, BACK, BOTTOM, FRONT);}
void rotate_b(Dice &dice) {rotate_swap(dice, TOP, FRONT, BOTTOM, BACK);}

struct Status {
  int x, y, cost;
  Dice d;
  bool operator<(const Status &s) const {return cost > s.cost;}
};

int main() {
  while (true) {
    int h, w;
    cin >> h >> w;
    if (h == 0) break;
    int board[h][w];
    rep (i, h) rep (j, w) cin >> board[i][j];
    int x1, y1, x2, y2;
    cin >> y1 >> x1 >> y2 >> x2;
    int dis[h][w][6][6][6];
    memset(dis, -1, sizeof(dis));
    priority_queue<Status> que;
    Dice d(6);
    rep (i, 6) d[i] = i + 1;
    que.push((Status){x1, y1, 0, d});
    while (!que.empty()) {
      Status now = que.top();
      que.pop();
      if (now.y == y2 && now.x == x2) {
	cout << now.cost << endl;
	break;
      }
      if (now.x < 0 || w <= now.x || now.y < 0 || h <= now.y) continue;
      if (dis[now.y][now.x][now.d[TOP]][now.d[FRONT]][now.d[RIGHT]] != -1) continue;
      dis[now.y][now.x][now.d[TOP]][now.d[FRONT]][now.d[RIGHT]] = now.cost;
      Dice d1 = now.d, d2 = now.d, d3 = now.d, d4 = now.d;
      rotate_r(d1);
      rotate_l(d2);
      rotate_f(d3);
      rotate_b(d4);
      if (now.x < w - 1) que.push((Status){now.x + 1, now.y, now.cost + d1[BOTTOM] * board[now.y][now.x + 1], d1});
      if (0 < now.x) que.push((Status){now.x - 1, now.y, now.cost + d2[BOTTOM] * board[now.y][now.x - 1], d2});
      if (now.y < h - 1) que.push((Status){now.x, now.y + 1, now.cost + d3[BOTTOM] * board[now.y + 1][now.x], d3});
      if (0 < now.y) que.push((Status){now.x, now.y - 1, now.cost + d4[BOTTOM] * board[now.y - 1][now.x], d4});
    }
  }
}
accuracy: 1
time_ms: 190
memory_kb: 1448
final_rank: 12

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <numeric>
#include <cctype>
#include <tuple>

#ifdef _MSC_VER
#include <agents.h>
#endif

#define FOR(i, a, b) for(int i = (a); i < (int)(b); ++i)
#define rep(i, n) FOR(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define REV(v) v.rbegin(), v.rend()
#define MEMSET(v, s) memset(v, s, sizeof(v))
#define X first
#define Y second

using namespace std;

typedef long long ll;
typedef pair<int, int> P;

std::istream &operator>>(std::istream &is, P &p){
	return is >> p.first >> p.second;
}

struct Dice{
private:
	static const int _roll[4][6], _turn[2][6];
public:
	vector<int> value;
	// 1-6 : top, near, right, left, far, bottom 

	Dice(){
		value.resize(6);
		for (int i = 0; i < 6; ++i) value[i] = i+1;
	}
	Dice(initializer_list<int> il){
		value.resize(6, -1);
		int cnt = 0;
		for (auto &e : il){
			value[cnt++] = e;
			if (cnt >= 6) break;
		}
		for (int i = 0; i < 6; ++i) if (value[i] < 0) value[i] = 5 - value[5 - i];
	}

	void roll(int dir){ // N, E, W, S
		vector<int> nxt(6);
		for (int i = 0; i < 6; ++i){
			nxt[i] = value[_roll[dir][i]];
		}
		value = nxt;
	}

	void turn(int dir){ // L, R
		vector<int> nxt(6);
		for (int i = 0; i < 6; ++i){
			nxt[i] = value[_turn[dir][i]];
		}
		value = nxt;
	}

	int &operator[](int i){
		return value[i];
	}
};

const int Dice::_roll[4][6] = {
	{ 1, 5, 2, 3, 0, 4 }, // North
	{ 3, 1, 0, 5, 4, 2 }, // East
	{ 2, 1, 5, 0, 4, 3 }, // West
	{ 4, 0, 2, 3, 5, 1 }, // South
};

const int Dice::_turn[2][6] = {
	{ 0, 3, 1, 4, 2, 5 }, // Left
	{ 0, 2, 4, 1, 3, 5 }, // Right
};

int board[10][10];

struct state{
	P first;
	Dice second;
	bool operator<(const state &r)const{
		if(first != r.first) return first < r.first;
		rep(i, 6) if (second.value[i] != r.second.value[i]) return second.value[i] < r.second.value[i];
		return false;
	}
};

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

int main(){
	int h, w;
	while (cin >> h >> w, h | w){
		rep(i, h) rep(j, w) cin >> board[i][j];
		P s, g;
		cin >> s >> g;

		map<state, int> m;

		priority_queue<pair<int, state>, vector<pair<int, state>>, greater<pair<int, state>>> q;
		q.push(make_pair(0, state{ s, Dice() }));
		int ans = -1;
		while (!q.empty()){
			int dist = q.top().first;
			state s = q.top().second;
			P &pos = s.first;
			Dice &d = s.second;
			q.pop();
			
			if (m[s] < dist) continue;
			if (s.first == g){
				ans = dist;
				break;
			}

			rep(i, 4){
				int nx = pos.second + dx[i], ny = pos.first + dy[i];
				if (nx < 0 || nx >= w || ny < 0 || ny >= h) continue;
				state nxt = s;
				nxt.second.roll(i);
				nxt.first = make_pair(ny, nx);
				if (m.count(nxt) && m[nxt] <= dist + nxt.second[5] * board[ny][nx]) continue;
				m[nxt] = dist + nxt.second[5] * board[ny][nx];
				q.push(make_pair(dist + nxt.second[5] * board[ny][nx], nxt));
			}
		}
		//cout << "+++";
		cout << ans << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 1392
final_rank: 11

code_snippet: #include <algorithm>
#include <cassert>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

constexpr int NUMBER_OF_FACES = 6;
enum FACE { TOP, BOTTOM, NORTH, SOUTH, WEST, EAST };

class dice {
private:
	int num[NUMBER_OF_FACES];

public:
	inline void roll(FACE a, FACE b, FACE c, FACE d) {
		swap(num[a], num[b]);
		swap(num[b], num[c]);
		swap(num[c], num[d]);
	}

	dice() {
		num[TOP] = 1;
		num[BOTTOM] = 6;
		num[NORTH] = 5;
		num[SOUTH] = 2;
		num[EAST] = 3;
		num[WEST] = 4;
	}

	dice(const dice& d) {
		num[TOP] = d[TOP];
		num[BOTTOM] = d[BOTTOM];
		num[NORTH] = d[NORTH];
		num[SOUTH] = d[SOUTH];
		num[EAST] = d[EAST];
		num[WEST] = d[WEST];
	}

	inline int encode() const {
		return (num[TOP] - 1) * NUMBER_OF_FACES * NUMBER_OF_FACES + (num[NORTH] - 1) * NUMBER_OF_FACES + (num[EAST] - 1);
	}

	const int& operator[] (FACE f) const { return num[f]; }
};

void north(dice& d) { d.roll(TOP, SOUTH, BOTTOM, NORTH); }
void east(dice& d) { d.roll(TOP, WEST, BOTTOM, EAST); }
void west(dice& d) { d.roll(TOP, EAST, BOTTOM, WEST); }
void south(dice& d) { d.roll(TOP, NORTH, BOTTOM, SOUTH); }


const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
void (*rotate_dice[4])(dice& d) = {east, south, west, north};

constexpr int MAX_SIZE = 10;
constexpr int INF = 0xfffffff;

int h, w;
int gx, gy;
int field[MAX_SIZE][MAX_SIZE];

typedef int weight;
struct state {
	int x, y;
	dice d;
	weight dist;
	state(int x, int y, const dice& d, weight dist):x(x), y(y), d(d), dist(dist){}

	bool operator>(const state& s) const {
		return dist > s.dist;
	}
};

inline bool out(int x, int y) {
	return x < 0 || x >= w || y < 0 || y >= h;
}

weight dijkstra(int sx, int sy, dice d) {
	priority_queue<state, vector<state>, greater<state> > que;
	vector<vector<vector<weight>>> dist(h, vector<vector<weight>>(w, vector<weight>(NUMBER_OF_FACES*NUMBER_OF_FACES*NUMBER_OF_FACES, INF)));
	dist[sy][sx][d.encode()] = 0;
	que.push(state(sx, sy, d, 0));

	while(!que.empty()) {
		const state s = que.top();
		que.pop();

		if(dist[s.y][s.x][s.d.encode()] < s.dist)
			continue;

		if(s.x == gx && s.y == gy)
			return s.dist;

		for(int i = 0; i < 4; ++i) {
			const int nx = s.x + dx[i];
			const int ny = s.y + dy[i];
			if(out(nx, ny)) continue;
			dice next_d(s.d);
			rotate_dice[i](next_d);

			const int next_dist = s.dist + next_d[BOTTOM] * field[ny][nx];
			const int value = next_d.encode();
			if(dist[ny][nx][value] > next_dist) {
				dist[ny][nx][value] = next_dist;
				que.push(state(nx, ny, next_d, next_dist));
			}
		}
	}

	assert(false);
}

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	while(cin >> h >> w && h) {
		for(int i = 0; i < h; ++i) {
			for(int j = 0; j < w; ++j) {
				cin >> field[i][j];
			}
		}

		int sx, sy;
		cin >> sy >> sx >> gy >> gx;

		cout << dijkstra(sx, sy, dice()) << endl;
	}

	return EXIT_SUCCESS;
}
accuracy: 1
time_ms: 20
memory_kb: 1356
final_rank: 4

code_snippet: #include <algorithm>
#include <cassert>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

enum FACE { TOP, BOTTOM, NORTH, SOUTH, WEST, EAST };

class dice {
private:
	int num[6];

public:
	inline void roll(FACE a, FACE b, FACE c, FACE d) {
		swap(num[a], num[b]);
		swap(num[b], num[c]);
		swap(num[c], num[d]);
	}

	dice() {
		num[TOP] = 1;
		num[BOTTOM] = 6;
		num[NORTH] = 5;
		num[SOUTH] = 2;
		num[EAST] = 3;
		num[WEST] = 4;
	}

	dice(const dice& d) {
		num[TOP] = d[TOP];
		num[BOTTOM] = d[BOTTOM];
		num[NORTH] = d[NORTH];
		num[SOUTH] = d[SOUTH];
		num[EAST] = d[EAST];
		num[WEST] = d[WEST];
	}

	int encode() const {
		return (num[TOP] - 1) * 6 * 6 + (num[NORTH] - 1) * 6 + (num[EAST] - 1);
	}

	const int& operator[] (FACE f) const { return num[f]; }
};

void north(dice& d) { d.roll(TOP, SOUTH, BOTTOM, NORTH); }
void east(dice& d) { d.roll(TOP, WEST, BOTTOM, EAST); }
void west(dice& d) { d.roll(TOP, EAST, BOTTOM, WEST); }
void south(dice& d) { d.roll(TOP, NORTH, BOTTOM, SOUTH); }


const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
void (*func[4])(dice& d) = {east, south, west, north};

constexpr int MAX_SIZE = 10;
constexpr int INF = 0xfffffff;

int h, w;
int gx, gy;
int field[MAX_SIZE][MAX_SIZE];

typedef int weight;
vector<weight> dist;
struct state {
	int x, y;
	dice d;
	weight dist;
	state(int x, int y, const dice& d, weight dist):x(x), y(y), d(d), dist(dist){}

	bool operator>(const state& s) const {
		return dist > s.dist;
	}
};

inline bool out(int x, int y) {
	return x < 0 || x >= w || y < 0 || y >= h;
}

weight dijkstra(int sx, int sy, dice d) {
	priority_queue<state, vector<state>, greater<state> > que;
	vector<vector<vector<weight>>> dist(h, vector<vector<weight>>(w, vector<weight>(6*6*6, INF)));
	dist[sy][sx][d.encode()] = 0;
	que.push(state(sx, sy, d, 0));

	while(!que.empty()) {
		const state s = que.top();
		que.pop();

		if(dist[s.y][s.x][s.d.encode()] < s.dist)
			continue;

		if(s.x == gx && s.y == gy)
			return s.dist;

		for(int i = 0; i < 4; ++i) {
			const int nx = s.x + dx[i];
			const int ny = s.y + dy[i];
			if(out(nx, ny)) continue;
			dice next_d(s.d);
			func[i](next_d);

			const int next_dist = s.dist + next_d[BOTTOM] * field[ny][nx];
			const int value = next_d.encode();
			if(dist[ny][nx][value] > next_dist) {
				dist[ny][nx][value] = next_dist;
				que.push(state(nx, ny, next_d, next_dist));
			}
		}
	}

	assert(false);
}

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	while(cin >> h >> w && h) {
		for(int i = 0; i < h; ++i) {
			for(int j = 0; j < w; ++j) {
				cin >> field[i][j];
			}
		}

		int sx, sy;
		cin >> sy >> sx >> gy >> gx;

		cout << dijkstra(sx, sy, dice()) << endl;
	}

	return EXIT_SUCCESS;
}
accuracy: 1
time_ms: 10
memory_kb: 1352
final_rank: 1

code_snippet: #include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;

#define dump(a) (cerr << (#a) << " = " << (a) << endl)

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

template<typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
	os << '(' << p.first << ", " << p.second << ')';
	return os;
}

template<class Tuple, unsigned Index>
void print_tuple(ostream& os, const Tuple& t) {}

template<class Tuple, unsigned Index, class Type, class... Types>
void print_tuple(ostream& os, const Tuple& t) {
	if(Index > 0) os << ", ";
	os << get<Index>(t);
	print_tuple<Tuple, Index + 1, Types...>(os, t);
}

template<class... Types>
ostream& operator<<(ostream& os, const tuple<Types...>& t) {
	os << '(';
	print_tuple<tuple<Types...>, 0, Types...>(os, t);
	return os << ')';
}

template<class Iterator>
ostream& dump_range(ostream&, Iterator, const Iterator&);

template<typename T>
ostream& operator<<(ostream& os, vector<T> c) {
	return dump_range(os, c.cbegin(), c.cend());
}

template<class Iterator>
ostream& dump_range(ostream& os, Iterator first, const Iterator& last) {
	os << '[';
	for(int i = 0; first != last; ++i, ++first) {
		if(i) os << ", ";
		os << *first;
	}
	return os << ']';
}

enum FACE { TOP, BOTTOM, NORTH, SOUTH, WEST, EAST };

class dice {
private:
	int num[6];

public:
	inline void roll(FACE a, FACE b, FACE c, FACE d) {
		swap(num[a], num[b]);
		swap(num[b], num[c]);
		swap(num[c], num[d]);
	}

	dice() {
		num[TOP] = 1;
		num[BOTTOM] = 6;
		num[NORTH] = 5;
		num[SOUTH] = 2;
		num[EAST] = 3;
		num[WEST] = 4;
	}

	dice(const dice& d) {
		num[TOP] = d[TOP];
		num[BOTTOM] = d[BOTTOM];
		num[NORTH] = d[NORTH];
		num[SOUTH] = d[SOUTH];
		num[EAST] = d[EAST];
		num[WEST] = d[WEST];
	}

	int encode() const {
		return (num[TOP] - 1) * 6 * 6 + (num[NORTH] - 1) * 6 + (num[EAST] - 1);
	}

	const int& operator[] (FACE f) const { return num[f]; }
};

void north(dice& d) { d.roll(TOP, SOUTH, BOTTOM, NORTH); }
void east(dice& d) { d.roll(TOP, WEST, BOTTOM, EAST); }
void west(dice& d) { d.roll(TOP, EAST, BOTTOM, WEST); }
void south(dice& d) { d.roll(TOP, NORTH, BOTTOM, SOUTH); }

constexpr int MAX_SIZE = 10;
constexpr int INF = 0xfffffff;
int h, w;
int gx, gy;
int field[MAX_SIZE][MAX_SIZE];

const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
void (*func[4])(dice& d) = { east, south, west, north};

bool visited[MAX_SIZE][MAX_SIZE][6];

bool out(int x, int y) {
	return x < 0 || x >= w || y < 0 || y >= h;
}

typedef int weight;
vector<weight> dist;
struct state {
	int x, y;
	dice d;
	weight dist;
	state(int x, int y, const dice& d, weight dist):x(x), y(y), d(d), dist(dist){}

	bool operator>(const state& s) const {
		return dist > s.dist;
	}
};

weight dijkstra(int sx, int sy, dice d) {
	priority_queue<state, vector<state>, greater<state> > que;
	vector<vector<vector<weight>>> dist(h, vector<vector<weight>>(w, vector<weight>(6*6*6, INF)));
	dist[sy][sx][d.encode()] = 0;
	que.push(state(sx, sy, d, 0));

	while(!que.empty()) {
		const state s = que.top();
		que.pop();

		if(dist[s.y][s.x][s.d.encode()] < s.dist)
			continue;

		if(s.x == gx && s.y == gy)
			return s.dist;

		for(int i = 0; i < 4; ++i) {
			const int nx = s.x + dx[i];
			const int ny = s.y + dy[i];
			if(out(nx, ny)) continue;
			dice next_d(s.d);
			func[i](next_d);
			const int next_dist = s.dist + next_d[BOTTOM] * field[ny][nx];
			if(dist[ny][nx][next_d.encode()] > next_dist) {
				dist[ny][nx][next_d.encode()] = next_dist;
				que.push(state(nx, ny, next_d, next_dist));
			}
		}
	}

	return -1;
}


int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	memset(visited, false, sizeof(visited));

	while(cin >> h >> w && h) {
		for(int i = 0; i < h; ++i) {
			for(int j = 0; j < w; ++j) {
				cin >> field[i][j];
			}
		}

		int sx, sy;
		cin >> sy >> sx >> gy >> gx;

		cout << dijkstra(sx, sy, dice()) << endl;
	}

	return EXIT_SUCCESS;
}
accuracy: 1
time_ms: 20
memory_kb: 1352
final_rank: 3

code_snippet: #include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <vector>

#define X first
#define Y second
#define P first
#define S second
#define C first
#define D second
#define mp(x, y) make_pair(x, y)

using namespace std;
typedef ostringstream OSS;
typedef pair<int, int> PII;
typedef pair<PII, string> PIIS;
typedef pair<int, PIIS> PIIIS;

struct die_t {
	int top, front, right, left, back, bottom;
	die_t ( int t, int f, int r, int l, int bk, int b )
		: top(t), front(f), right(r), left(l), back(bk), bottom(b) { }
	die_t ( string dice ) {
		top = dice[0] - '0'; front = dice[1] - '0'; right = dice[2] - '0';
		left = dice[3] - '0'; back = dice[4] - '0'; bottom = dice[5] - '0';
	}
	void rotate_swap ( int &a, int &b, int &c, int &d ) {
		swap(a, b); swap(b, c); swap(c, d);
	}
	void rotate_right ( void ) { rotate_swap(top,left,bottom,right); }
	void rotate_left ( void ) { rotate_swap(top,right,bottom,left); }
	void rotate_front ( void ) { rotate_swap(top,back,bottom,front); }
	void rotate_back ( void ) { rotate_swap(top,front,bottom,back); }
	void rotate_cw ( void ) { rotate_swap(back,left,front,right); }
	void rotate_cc ( void ) { rotate_swap(back,right,front,left); }
	bool rotate_set ( int n, int t, int f, int r, int l, int bk, int b ) {
		for (int i = 0; i < 6; ++i) {
			for (int j = 0; j < 4; ++j) {
				if (n == equal_num(t, f, r, l, bk, b)) { return true; }
				rotate_cw();
			}
			(i&1 ? rotate_front() : rotate_right());
		}
		return false;
	}
	int equal_num ( int t, int f, int r, int l, int bk, int b ) {
		return (top==t) + (front==f) + (right==r) + (left==l) + (back==bk) + (bottom==b);
	}
	string toString ( void ) {
		OSS os; os << top << front << right << left << back << bottom;
		return os.str();
	}
};

const int INF = 1 << 29;
const int MAX_WH = 10;

int main ( void )
{
	vector<string> vs;
	die_t dd("123456");
	for (int i = 0; i < 6; ++i) {
		for (int j = 0; j < 4; ++j) {
			vs.push_back(dd.toString());
			dd.rotate_cw();
		}
		if (i&1) { dd.rotate_front(); }
		else { dd.rotate_right(); }
	}

	int h, w, mat[MAX_WH][MAX_WH];

	while (cin >> h >> w, h | w) {
		map<string, int> M[MAX_WH][MAX_WH];
		for (int y = 0; y < h; ++y) {
			for (int x = 0; x < w; ++x) {
				cin >> mat[y][x];
				for (int i = 0, I = vs.size(); i < I; ++i) {
					M[y][x].insert(mp(vs[i], INF));
				}
			}
		}

		PII s, g;
		cin >> s.Y >> s.X;
		cin >> g.Y >> g.X;

		die_t dice("123456");
		priority_queue<PIIIS, vector<PIIIS>, greater<PIIIS> > Q;
		M[s.Y][s.X]["123456"] = 0;
		Q.push(mp(0, mp(mp(s.X, s.Y), dice.toString())));

		while (!Q.empty()) {
			PIIIS piiis = Q.top(); Q.pop();
			PIIS piis = piiis.D;
			PII p = piis.P;

			if (M[p.Y][p.X][piis.S] < piiis.C) { continue; }

			string s = piis.S, s1, s2, s3, s4;
			die_t d1(s), d2(s), d3(s), d4(s);
			d1.rotate_right(); s1 = d1.toString();
			d2.rotate_left(); s2 = d2.toString();
			d3.rotate_front(); s3 = d3.toString();
			d4.rotate_back(); s4 = d4.toString();

			if (p.X + 1 < w
			&& M[p.Y][p.X+1][s1] > M[p.Y][p.X][s] + mat[p.Y][p.X+1] * d1.bottom) {
				M[p.Y][p.X+1][s1] = M[p.Y][p.X][s] + mat[p.Y][p.X+1] * d1.bottom;
				Q.push(mp(M[p.Y][p.X+1][s1], mp(mp(p.X+1, p.Y), s1)));
			}
			if (p.X - 1 >=0
			&& M[p.Y][p.X-1][s2] > M[p.Y][p.X][s] + mat[p.Y][p.X-1] * d2.bottom) {
				M[p.Y][p.X-1][s2] = M[p.Y][p.X][s] + mat[p.Y][p.X-1] * d2.bottom;
				Q.push(mp(M[p.Y][p.X-1][s2], mp(mp(p.X-1, p.Y), s2)));
			}
			if (p.Y + 1 < h
			&& M[p.Y+1][p.X][s3] > M[p.Y][p.X][s] + mat[p.Y+1][p.X] * d3.bottom) {
				M[p.Y+1][p.X][s3] = M[p.Y][p.X][s] + mat[p.Y+1][p.X] * d3.bottom;
				Q.push(mp(M[p.Y+1][p.X][s3], mp(mp(p.X, p.Y+1), s3)));
			}
			if (p.Y - 1 >=0
			&& M[p.Y-1][p.X][s4] > M[p.Y][p.X][s] + mat[p.Y-1][p.X] * d4.bottom) {
				M[p.Y-1][p.X][s4] = M[p.Y][p.X][s] + mat[p.Y-1][p.X] * d4.bottom;
				Q.push(mp(M[p.Y-1][p.X][s4], mp(mp(p.X, p.Y-1), s4)));
			}
		}

		int ans = INF;
		for (int i = 0, I = vs.size(); i < I; ++i) {
			ans = min(ans, M[g.Y][g.X][vs[i]]);
		}
		cout << ans << endl;

	}
	return 0;
}
accuracy: 1
time_ms: 550
memory_kb: 1436
final_rank: 16

code_snippet: #include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <vector>

#define X first
#define Y second
#define P first
#define S second
#define mp(x, y) make_pair(x, y)

using namespace std;
typedef ostringstream OSS;
typedef pair<int, int> PII;
typedef pair<PII, string> PIIS;

struct die_t {
	int top, front, right, left, back, bottom;
	die_t ( int t, int f, int r, int l, int bk, int b )
		: top(t), front(f), right(r), left(l), back(bk), bottom(b) { }
	die_t ( string dice ) {
		top = dice[0] - '0'; front = dice[1] - '0'; right = dice[2] - '0';
		left = dice[3] - '0'; back = dice[4] - '0'; bottom = dice[5] - '0';
	}
	void rotate_swap ( int &a, int &b, int &c, int &d ) {
		swap(a, b); swap(b, c); swap(c, d);
	}
	void rotate_right ( void ) { rotate_swap(top,left,bottom,right); }
	void rotate_left ( void ) { rotate_swap(top,right,bottom,left); }
	void rotate_front ( void ) { rotate_swap(top,back,bottom,front); }
	void rotate_back ( void ) { rotate_swap(top,front,bottom,back); }
	void rotate_cw ( void ) { rotate_swap(back,left,front,right); }
	void rotate_cc ( void ) { rotate_swap(back,right,front,left); }
	bool rotate_set ( int n, int t, int f, int r, int l, int bk, int b ) {
		for (int i = 0; i < 6; ++i) {
			for (int j = 0; j < 4; ++j) {
				if (n == equal_num(t, f, r, l, bk, b)) { return true; }
				rotate_cw();
			}
			(i&1 ? rotate_front() : rotate_right());
		}
		return false;
	}
	int equal_num ( int t, int f, int r, int l, int bk, int b ) {
		return (top==t) + (front==f) + (right==r) + (left==l) + (back==bk) + (bottom==b);
	}
	string toString ( void ) {
		OSS os; os << top << front << right << left << back << bottom;
		return os.str();
	}
};

const int INF = 1 << 29;
const int MAX_WH = 10;

int main ( void )
{
	vector<string> vs;
	die_t dd("123456");
	for (int i = 0; i < 6; ++i) {
		for (int j = 0; j < 4; ++j) {
			vs.push_back(dd.toString());
			dd.rotate_cw();
		}
		if (i&1) { dd.rotate_front(); }
		else { dd.rotate_right(); }
	}

	int h, w, mat[MAX_WH][MAX_WH];

	while (cin >> h >> w, h | w) {
		map<string, int> M[MAX_WH][MAX_WH];
		for (int y = 0; y < h; ++y) {
			for (int x = 0; x < w; ++x) {
				cin >> mat[y][x];
				for (int i = 0, I = vs.size(); i < I; ++i) {
					M[y][x].insert(mp(vs[i], INF));
				}
			}
		}

		PII s, g;
		cin >> s.Y >> s.X;
		cin >> g.Y >> g.X;

		die_t dice("123456");
		queue<PIIS> Q;
		M[s.Y][s.X]["123456"] = 0;
		Q.push(mp(mp(s.X, s.Y), dice.toString()));

		while (!Q.empty()) {
			PIIS piis = Q.front(); Q.pop();
			PII p = piis.P;
			string s = piis.S, s1, s2, s3, s4;
			die_t d1(s), d2(s), d3(s), d4(s);
			d1.rotate_right(); s1 = d1.toString();
			d2.rotate_left(); s2 = d2.toString();
			d3.rotate_front(); s3 = d3.toString();
			d4.rotate_back(); s4 = d4.toString();
			int now = M[p.Y][p.X][s];

			if (p.X + 1 < w
			&& M[p.Y][p.X+1][s1] > now + mat[p.Y][p.X+1] * d1.bottom) {
				M[p.Y][p.X+1][s1] = now + mat[p.Y][p.X+1] * d1.bottom;
				Q.push(mp(mp(p.X+1, p.Y), s1));
			}
			if (p.X - 1 >=0
			&& M[p.Y][p.X-1][s2] > now + mat[p.Y][p.X-1] * d2.bottom) {
				M[p.Y][p.X-1][s2] = now + mat[p.Y][p.X-1] * d2.bottom;
				Q.push(mp(mp(p.X-1, p.Y), s2));
			}
			if (p.Y + 1 < h
			&& M[p.Y+1][p.X][s3] > now + mat[p.Y+1][p.X] * d3.bottom) {
				M[p.Y+1][p.X][s3] = now + mat[p.Y+1][p.X] * d3.bottom;
				Q.push(mp(mp(p.X, p.Y+1), s3));
			}
			if (p.Y - 1 >=0
			&& M[p.Y-1][p.X][s4] > now + mat[p.Y-1][p.X] * d4.bottom) {
				M[p.Y-1][p.X][s4] = now + mat[p.Y-1][p.X] * d4.bottom;
				Q.push(mp(mp(p.X, p.Y-1), s4));
			}
		}

		int ans = INF;
		for (int i = 0, I = vs.size(); i < I; ++i) {
			ans = min(ans, M[g.Y][g.X][vs[i]]);
		}
		cout << ans << endl;

	}
	return 0;
}
accuracy: 1
time_ms: 930
memory_kb: 1452
final_rank: 18