闲谈:这个题目该怎么写呢?我们很容易知道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
京公网安备 11010502036488号