题目
思路
这道题其实思考难度不大,
主要是有一堆细节,码量也很大,
非常考验bfs的基础,我调了两个多小时。
我们需要分情况处理,分成用瞬移和不用瞬移两板块;
然后再分别判断是否要隐身,维护一下状态即可。
代码
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int dx[9]={
0,1,0,0,-1,1,1,-1,-1};
int dy[9]={
0,0,1,-1,0,1,-1,-1,1};
int n,m,y,s,d,tx,ty,v[351][351][20][20],ans=2147483647,ans1,ans2;
string a[410][410];
char c;
struct node
{
int x,y,c,ys,sy;
}f[2000004];
void bfs()
{
v[f[1].x][f[1].y][0][0]=1;
//cout<<f[1].x<<' '<<f[1].y<<endl;
int dxd[5]={
0,0,d,0,-d};
int dyd[5]={
0,d,0,-d,0};
int hd=0,tl=1;
while(hd!=tl)
{
hd=hd%2000000+1;
if(f[hd].c>=ans)
continue;
for(int i=1; i<=8; i++)
{
int xx=f[hd].x+dx[i];
int yy=f[hd].y+dy[i];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m)
{
if(a[xx][yy]!="-1"&&a[xx][yy]!="sb"&&v[xx][yy][f[hd].ys][f[hd].sy]==0)
{
tl=tl%2000000+1;
v[xx][yy][f[hd].ys][f[hd].sy]=1;
f[tl]=(node){
xx,yy,f[hd].c+1,f[hd].ys,f[hd].sy};
if(xx==tx&&yy==ty)
{
// cout<<ans<<' '<<ans1<<' '<<ans2<<endl;
if(f[tl].c<ans)
{
ans=f[tl].c;
ans1=f[tl].ys;
ans2=f[tl].sy;
}
else if(f[tl].c==ans&&f[tl].ys+f[tl].sy<ans1+ans2)
{
ans=f[tl].c;
ans1=f[tl].ys;
ans2=f[tl].sy;
}
else if(f[tl].c==ans&&f[tl].ys+f[tl].sy==ans1+ans2&&f[tl].ys<ans1)
{
ans=f[tl].c;
ans1=f[tl].ys;
ans2=f[tl].sy;
}
}
}
if(a[xx][yy]=="-1"&&f[hd].ys<y&&v[xx][yy][f[hd].ys+1][f[hd].sy]==0)
{
tl=tl%2000000+1;
v[xx][yy][f[hd].ys+1][f[hd].sy]=1;
f[tl]=(node){
xx,yy,f[hd].c+1,f[hd].ys+1,f[hd].sy};
if(xx==tx&&yy==ty)
{
// cout<<ans<<' '<<ans1<<' '<<ans2<<endl;
if(f[tl].c<ans)
{
ans=f[tl].c;
ans1=f[tl].ys;
ans2=f[tl].sy;
}
else if(f[tl].c==ans&&f[tl].ys+f[tl].sy<ans1+ans2)
{
ans=f[tl].c;
ans1=f[tl].ys;
ans2=f[tl].sy;
}
else if(f[tl].c==ans&&f[tl].ys+f[tl].sy==ans1+ans2&&f[tl].ys<ans1)
{
ans=f[tl].c;
ans1=f[tl].ys;
ans2=f[tl].sy;
}
}
}
}
}
for(int i=1; i<=4; i++)
{
int xx=f[hd].x+dxd[i];
int yy=f[hd].y+dyd[i];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m)
{
if(a[xx][yy]!="-1"&&a[xx][yy]!="sb"&&f[hd].sy<s&&v[xx][yy][f[hd].ys][f[hd].sy+1]==0)
{
tl=tl%2000000+1;
v[xx][yy][f[hd].ys][f[hd].sy+1]=1;
f[tl]=(node){
xx,yy,f[hd].c+1,f[hd].ys,f[hd].sy+1};
if(xx==tx&&yy==ty)
{
// cout<<ans<<' '<<ans1<<' '<<ans2<<endl;
if(f[tl].c<ans)
{
ans=f[tl].c;
ans1=f[tl].ys;
ans2=f[tl].sy;
}
else if(f[tl].c==ans&&f[tl].ys+f[tl].sy<ans1+ans2)
{
ans=f[tl].c;
ans1=f[tl].ys;
ans2=f[tl].sy;
}
else if(f[tl].c==ans&&f[tl].ys+f[tl].sy==ans1+ans2&&f[tl].ys<ans1)
{
ans=f[tl].c;
ans1=f[tl].ys;
ans2=f[tl].sy;
}
}
}
if(a[xx][yy]=="-1"&&f[hd].sy<s&&f[hd].ys<y&&v[xx][yy][f[hd].ys+1][f[hd].sy+1]==0)
{
tl=tl%2000000+1;
v[xx][yy][f[hd].ys+1][f[hd].sy+1]=1;
f[tl]=(node){
xx,yy,f[hd].c+1,f[hd].ys+1,f[hd].sy+1};
if(xx==tx&&yy==ty)
{
// cout<<ans<<' '<<ans1<<' '<<ans2<<endl;
if(f[tl].c<ans)
{
ans=f[tl].c;
ans1=f[tl].ys;
ans2=f[tl].sy;
}
else if(f[tl].c==ans&&f[tl].ys+f[tl].sy<ans1+ans2)
{
ans=f[tl].c;
ans1=f[tl].ys;
ans2=f[tl].sy;
}
else if(f[tl].c==ans&&f[tl].ys+f[tl].sy==ans1+ans2&&f[tl].ys<ans1)
{
ans=f[tl].c;
ans1=f[tl].ys;
ans2=f[tl].sy;
}
}
}
}
}
}
if(ans!=2147483647)
cout<<ans<<' '<<ans1<<' '<<ans2;
else
cout<<-1;
}
void ycl()
{
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
if(a[i][j]=="S")
f[1].x=i,f[1].y=j,v[i][j][0][0]=1;
int shuzi=0;
for(int k=0; k<=a[i][j].size()-1; k++)
shuzi=shuzi*10+(a[i][j][k]-48);
if(shuzi>=1&&shuzi<=350&&shuzi!='T'-48&&shuzi!='S'-48)
{
if(a[i][j]=="1")
{
a[i][j]="sb";
continue;
}
string z=a[i][j];
int ca=0;
for(int k=0; k<=z.size()-1; k++)
ca=ca*10+(z[k]-48);
int caa=0;
ca--;
for(int k=max(i-ca,1); k<=min(i+ca,n); k++)
{
for(int w=max(j-caa,1); w<=min(j+caa,m); w++)
{
//cout<<k<<" "<<w<<" ";
if(k==i&&w==j)
a[i][j]="sb";
if(a[k][w]=="."||a[k][w]=="T")
a[k][w]="-1";
}
if(k<i)
caa++;
else
caa--;
}
}
}
}
int main()
{
// freopen("bandit18.in","r",stdin);
// freopen("xxx.out","w",stdout);
cin>>n>>m>>y>>s>>d;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
c=getchar();
while(c!='S'&&c!='T'&c!='.'&&(c<'0'||c>'9'))
c=getchar();
if(c=='S'||c=='T'||c=='.')
{
a[i][j]=c;
if(a[i][j]=="T")
tx=i,ty=j;
}
if(c>='0'&&c<='9')
{
a[i][j]=c;
string ccc;
char cc=getchar();
while(cc>='0'&&cc<='9')
{
ccc=ccc+cc;
cc=getchar();
}
a[i][j]+=ccc;
}
}
ycl();
// for(int i=1; i<=n; i++,cout<<endl)
// for(int j=1; j<=m; j++)
// cout<<a[i][j]<<" ";
bfs();
return 0;
}