//bfs+deque,方法同P4667
//坑点:掉落过程中碰到D也算是到达!
#include <bits/stdc++.h>
#define mp(x,y,z,m) make_pair(make_pair(x,y),make_pair(z,m))
using namespace std;
int n,m,i,j,sx,sy,ex,ey,ans=1e9,nx,ny,ng,n_step,dy[2]={1,-1},xx,xy,temp;char a[505][505];bool flag=false,vis[505][505];
deque <pair<pair<int,int>,pair<int,int> > >d;//1为向下,2为向上
//元素顺序:x坐标,y坐标,重力方向,翻转次数
int down(int x,int y,int g)//下降不影响y坐标,只会干扰x坐标(只返回新的x坐标,如果掉出去返回0)
{
if (x==ex&&y==ey) return 604;
if (g==1)
{
while (a[x+1][y]!='#')
{
x++;
if (x==ex&&y==ey) return 604;//特判在下落中落到终点
if (x>=n) return 0;
}
return x;
}
else
{
while (a[x-1][y]!='#')
{
x--;
if (x==ex&&y==ey) return 604;
if (x<=1) return 0;
}
return x;
}
}
void bfs()
{
vis[sx][sy]=true;
//cout<<1;
int temp1=down(sx,sy,1),temp2=down(sx,sy,2);
//cout<<temp1<<' '<<temp2<<endl;
if (temp1==604) {flag=true;ans=0;return;}
if (temp2==604) {flag=true;ans=1;return;}
if (temp1!=0) {d.push_front(mp(temp1,sy,1,0));vis[temp1][sy]=true;}
if (temp2!=0) {d.push_back(mp(temp2,sy,2,1));vis[temp2][sy]=true;}
while (!d.empty())
{
nx=d.front().first.first;ny=d.front().first.second;ng=d.front().second.first;n_step=d.front().second.second;d.pop_front();
//cout<<nx<<' '<<ny<<' '<<ng<<' '<<n_step<<endl;
if (nx==ex&&ny==ey) {flag=true;ans=min(ans,n_step);continue;}
for (i=0;i<2;++i)
{
xx=nx;xy=ny+dy[i];
if (xx<1||xx>n||xy<1||xy>m||a[xx][xy]=='#') continue;
temp=down(xx,xy,ng); if (temp==604) {flag=true;ans=min(ans,n_step);continue;}
if (temp==0||n_step>=ans||vis[temp][xy]) continue;
d.push_front(mp(temp,xy,ng,n_step));
vis[temp][xy]=true;
}
temp=down(nx,ny,3-ng);if (temp==604) {flag=true;ans=min(ans,n_step+1);continue;}
if (temp!=0&&(!vis[temp][ny]))
{
d.push_back(mp(temp,ny,3-ng,n_step+1));
vis[temp][ny]=true;
}
}
}
int main()
{
//freopen("gravity.in","r",stdin);
//freopen("gravity.out","w",stdout);
cin>>n>>m;
for (i=1;i<=n;++i)
{
for (j=1;j<=m;++j)
{
cin>>a[i][j];
if (a[i][j]=='C'){sx=i;sy=j;}
else if (a[i][j]=='D'){ex=i;ey=j;}
}
}
bfs();
if (flag) cout<<ans<<endl;
else cout<<-1;
return 0;
}
这是我原来的代码+AC记录 但是会对该数据输出错解1(正解应为-1,因为一开始的重力反转要在不满足条件1、2的情况下进行)
5 5
##D##
#C..#
#...#
#...#
#.###