题意:给定一个n\times m 的矩阵,然后有些单元格上有柱子。灯光穿过柱子的时候,可以直接穿过,也可以花费 1 ,向四个方向折射。现有一束光从第一行右边射出,然后要求从最后一行右边射出,求最少的花费。
思路:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1000+5,mod=1e9+7;
const int inf=0x3f3f3f3f;
int n,m;
int cost[maxn][maxn][4];
char grid[maxn][maxn];
int Move[][2]={{-1,0},{0,1},{1,0},{0,-1}};
struct node
{
int x,y,dir;
};
void bfs()
{
queue<node> q;
q.push({n,m,3});
cost[n][m][3]=0;
while(!q.empty())
{
node t=q.front();
q.pop();
int nx=t.x+Move[t.dir][0];
int ny=t.y+Move[t.dir][1];
int c=cost[t.x][t.y][t.dir];
if(nx>=1&&nx<=n&&ny>=1&&ny<=m)
{
if(cost[nx][ny][t.dir]>c)
{
cost[nx][ny][t.dir]=c;
q.push({nx,ny,t.dir});
}
}
if(grid[t.x][t.y]=='#')
{
for(int i=0;i<4;++i)
{
if(i!=t.dir&&cost[t.x][t.y][i]>c+1)
{
cost[t.x][t.y][i]=c+1;
q.push({t.x,t.y,i});
}
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%s",grid[i]+1);
memset(cost,inf,sizeof(cost));
bfs();
if(cost[1][1][3]!=inf)
printf("%d\n",cost[1][1][3]);
else
puts("-1");
return 0;
}
0/1 BFS
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1000+5,mod=1e9+7;
const int inf=0x3f3f3f3f;
int n,m;
int cost[maxn][maxn][4];
char grid[maxn][maxn];
int Move[][2]={{-1,0},{0,1},{1,0},{0,-1}};
struct node
{
int x,y,dir;
};
void bfs()
{
deque<node> q;
q.push_back({n,m,3});
cost[n][m][3]=0;
while(!q.empty())
{
node t=q.front();
q.pop_front();
if(cost[1][1][3]!=inf)
break;
int nx=t.x+Move[t.dir][0];
int ny=t.y+Move[t.dir][1];
int c=cost[t.x][t.y][t.dir];
if(nx>=1&&nx<=n&&ny>=1&&ny<=m)
{
if(cost[nx][ny][t.dir]>c)
{
cost[nx][ny][t.dir]=c;
q.push_front({nx,ny,t.dir});
}
}
if(grid[t.x][t.y]=='#')
{
for(int i=0;i<4;++i)
{
if(i!=t.dir&&cost[t.x][t.y][i]>c+1)
{
cost[t.x][t.y][i]=c+1;
q.push_back({t.x,t.y,i});
}
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%s",grid[i]+1);
memset(cost,inf,sizeof(cost));
bfs();
if(cost[1][1][3]!=inf)
printf("%d\n",cost[1][1][3]);
else
puts("-1");
return 0;
}
BFS
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1000+5,mod=1e9+7;
const int inf=0x3f3f3f3f;
int n,m;
char s[maxn];
vector<int> G[maxn<<1];
bool visit[maxn<<1];
int depth[maxn<<1];
void bfs()
{
queue<int> q;
visit[n]=true;
q.push(n);
while(!q.empty())
{
int u=q.front();
q.pop();
for(auto v: G[u])
{
if(!visit[v])
{
visit[v]=true;
depth[v]=depth[u]+1;
q.push(v);
if(v==1)
return;
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
{
scanf("%s",s+1);
for(int j=1;j<=m;++j)
{
if(s[j]=='#')
{
G[i].push_back(j+n);
G[j+n].push_back(i);
}
}
}
bfs();
if(depth[1]||1==n)
printf("%d\n",depth[1]);
else
puts("-1");
return 0;
}