//一道广搜题,扩展时有三个状态左转、右转、前进; //收取宝藏可以在前进的时候判断;状态的标记可以用 //一个四维数组标记即:坐标,方向,宝藏是否全部拾取; # 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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-08 20:21:04