题目:
题解:
有一种很有意思的做法就是随便找一棵树向下沿出一条线,不能从右向左跨越这条线,如果从左向右跨越这条线的话就记为dis[1][x][y],那么只要是跨过了这条线就形成了一个环啦,最后的答案当然是dis[1][bx][by]
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define INF 1e9
using namespace std;
const int cc[8][2]={{1,0},{-1,0},{0,-1},{0,1},{1,1},{-1,-1},{-1,1},{1,-1}};
int dis[2][55][55],bx,by,r,c,caty,catx;char st[55][55];
struct hh{int x,y,id;};
void bfs()
{
queue<hh>q;
q.push((hh){bx,by,0});
memset(dis,0x7f,sizeof(dis));
dis[0][bx][by]=0;
while (!q.empty())
{
hh now=q.front(); q.pop();
for (int i=0;i<8;i++)
{
int xx=now.x+cc[i][0],yy=now.y+cc[i][1];
if (xx<1 || yy<1 || xx>r || yy>c || st[xx][yy]=='X') continue;
if (yy==caty && now.y>caty && now.x>catx) continue;
if (now.y==caty && yy>caty && now.x>catx)
{
if (dis[1][xx][yy]>dis[0][now.x][now.y]+1)
{
dis[1][xx][yy]=dis[0][now.x][now.y]+1;
q.push((hh){xx,yy,1});
}
}
else
{
if (dis[now.id][xx][yy]>dis[now.id][now.x][now.y]+1)
{
dis[now.id][xx][yy]=dis[now.id][now.x][now.y]+1;
q.push((hh){xx,yy,now.id});
}
}
}
}
printf("%d",dis[1][bx][by]);
}
int main()
{
int i,j;
scanf("%d%d",&r,&c);
bool vv=0;
for (i=1;i<=r;i++)
{
scanf("%s",st[i]+1);
for (j=1;j<=c;j++)
{
if (st[i][j]=='*') bx=i,by=j;
if (st[i][j]=='X' && !vv) vv=1,caty=j,catx=i;
}
}
bfs();
}