注意题目的黑体字,所有示例都只有一堆黄金。所以不存在开不开枪的状态;
//一道广搜题,扩展时有三个状态左转、右转、前进;
//收取宝藏可以在前进的时候判断;状态的标记可以用
//一个四维数组标记即:坐标,方向,宝藏是否全部拾取;
# include <queue>
# include <cstdio>
# include <cstring>
# include <iostream>
using namespace std;
int n,change[30][30],vis[30][30][4][2],sum,flag;
int d[4][2] = {0,-1,-1,0,0,1,1,0};
struct Point{
int m[30][30];
int x,y,f,step,t,flag;
Point operator = (const Point &a){
x = a.x;y = a.y;f = a.f;step = a.step;t = a.t;flag = a.flag;
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++) m[i][j] = a.m[i][j];
}
}
}s;
void bfs(){
queue <Point> q;
s.x = n-1;
s.y = s.step = s.t = s.flag= 0;s.f = 2;
vis[n-1][0][s.f][0] = 1;
q.push(s);
while(!q.empty())
{
Point temp = q.front();q.pop();
for(int i = 0;i < 3;i++){
Point e = temp;
if(e.x == n-1 && e.y == 0 && e.flag == 1){
e.step++;
flag = 1;
printf("%d\n",sum*1000 - e.step*10);
return ;
}
if(i == 0){
e.f = (e.f - 1 + 4) % 4,e.step++;
if(!vis[e.x][e.y][e.f][e.flag]){
vis[e.x][e.y][e.f][e.flag]=1,q.push(e);
}
}
else if(i == 1){
e.f = (e.f + 1) % 4,e.step++;
if(!vis[e.x][e.y][e.f][e.flag]){
vis[e.x][e.y][e.f][e.flag]=1,q.push(e);
}
}
else if(i == 2){
e.x += d[e.f][0],e.y += d[e.f][1],e.step++;
if(e.x>=0 && e.x<n && e.y>=0 && e.y<n && !vis[e.x][e.y][e.f][e.flag]
&& (e.m[e.x][e.y]==0 || e.m[e.x][e.y]==3)){
q.push(e);
vis[e.x][e.y][e.f][e.flag] = 1;
if(e.m[e.x][e.y] == 3){
e.m[e.x][e.y] = 0;
e.step++,e.t++;
if(e.t == sum) e.flag = 1;
vis[e.x][e.y][e.f][e.flag] = 1;
q.push(e);
}
}
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
int a,b,c,f = 0;
sum = flag = 0;
memset(change,0,sizeof(change));
memset(vis,0,sizeof(vis));
scanf("%d",&n);
while(scanf("%d%d%d",&a,&b,&c)&& a != -1){
change[b][c] = a;
if(a == 2 && !b && !c) f = 1;
if(a == 3) sum ++;
}
for(int i = 0;i < n;i++){
for(int k = 0,j = n - 1;k < n && j >= 0;k++,j--) s.m[j][i] = change[i][k];
}
if(f || !sum){
printf("-1\n"); continue;
}
else bfs();
if(!flag) printf("-1\n");
}
return 0;
}