闲谈:这个题目该怎么写呢?我们很容易知道2次使得横坐标移动3格/纵坐标移动3格为最佳对吧.我们首先分析下小的格子,先从1-1开始?那就只有一组解对吧,2-2也是一样的吧,都是只有在终点的地方有解对吧.3-3呢?合法位子必定有解.哈哈哈,看错题目了,题目说是无限空间,那么思路还是一样的啦,那么题目就成了,你在一个6-6的方格中如何从一个不是(3,3)到(3,3).
代码:
#include <bits/stdc++.h> using namespace std; const int N=10; struct vv{ int x,y,dir; }; queue<vv>q; int dis[N][N][4]; bool ck(int x,int y) { return x>=0&&y<=6&&x<=6&&y<=6; } int bfs(int x,int y) { int res=2e9; //上下左右四个方向 int dr[3][4][3]={ {{-2,0,1},{1,0,1},{0,-2,2},{0,1,2}},//立着的 {{-1,0,0},{2,0,0},{0,-1,1},{0,1,1}},//竖着的 {{-1,0,2},{1,0,2},{0,-1,0},{0,2,0}}//横着的. }; while(q.size()) { auto temp=q.front(); // cout<<temp.x<<' '<<temp.y<<' '<<temp.dir<<' '; // cout<<dis[temp.x][temp.y][temp.dir]<<endl; q.pop(); if(temp.x%3==0&&temp.y%3==0&&temp.dir==0) { int tx=((temp.x-3)+x)/3*2; int ty=((temp.y-3)+y)/3*2; if(tx<0||ty<0) continue; res=min(dis[temp.x][temp.y][temp.dir]+tx+ty,res); } for(int i=0;i<4;i++) { int at,bt,ct; at=temp.x+dr[temp.dir][i][0]; bt=temp.y+dr[temp.dir][i][1]; ct=dr[temp.dir][i][2]; if(!ck(at,bt)) continue; if(ct==1&&!ck(at+1,bt)) continue; if(ct==2&&!ck(at,bt+1)) continue; if(0x3f3f3f3f==dis[at][bt][ct]) { q.push({at,bt,ct}); dis[at][bt][ct]=dis[temp.x][temp.y][temp.dir]+1; } } } return res; } int main() { char c; while(cin>>c) { memset(dis,0x3f,sizeof dis); while(q.size()) q.pop(); int x,y,ans=0; cin>>x>>y; if(c=='U') {q.push({x%3+3,y%3+3,0});dis[x%3+3][y%3+3][0]=0;} if(c=='V') {q.push({x%3+3,y%3+3,1});dis[x%3+3][y%3+3][1]=0;} if(c=='H') {q.push({x%3+3,y%3+3,2});dis[x%3+3][y%3+3][2]=0;} x-=x%3; y-=y%3; ans=bfs(x,y); cout<<ans<<endl; } return 0; }//4