荆轲刺秦王
解题思路
这题为一道广搜
有很多种情况
代码量大了点
AC代码
#include<cmath>
#include<cstdio>
#include<iostream>
using namespace std;
int n,m,c1,c2,d,ex,ey,answer1=100000,answer2=100000,answer3=100000,answer4=100000,b[400][400],z[400][400],c[400][400][20][20];
int dx[8]={
-1,0,1,0,-1,1,1,-1};//特殊
int dy[8]={
0,1,0,-1,1,1,-1,-1};
string s;
struct node
{
int x,y,c1,c2,ans;
}p[10000005];
void fz(int ans,int c1,int c2)//赋值
{
answer1=ans;
answer2=c1;
answer3=c2;
answer4=c1+c2;
}
bool check(int x,int y)//判断
{
return x>=1&&x<=n&&y>=1&&y<=m;
}
void bfs()//bfs
{
int head=0,tail=1;
while(head<tail)
{
head++;
head%=10000000;
int ox=p[head].x,oy=p[head].y,o1=p[head].c1,o2=p[head].c2,oans=p[head].ans;
for(int i=0;i<8;i++)
{
int xx=ox+dx[i],yy=oy+dy[i];
if(check(xx,yy)&&!z[xx][yy])//不用瞬移
{
if(b[xx][yy])
{
if(o1+1<=c1&&!c[xx][yy][o1+1][o2])
{
c[xx][yy][o1+1][o2]=1;
p[++tail]=(node){
xx,yy,o1+1,o2,oans+1};
tail%=100000000;
if(xx==ex&&yy==ey)
{
if(oans+1<answer1)fz(oans+1,o1+1,o2);
else if(oans+1==answer1&&o1+1+o2<answer4)fz(oans+1,o1+1,o2);
else if(oans+1==answer1&&o1+1+o2==answer4&&o1+1<answer2)fz(oans+1,o1+1,o2);
}
}
}
else
{
if(!c[xx][yy][o1][o2])
{
c[xx][yy][o1][o2]=1;
p[++tail]=(node){
xx,yy,o1,o2,oans+1};
tail%=100000000;
if(xx==ex&&yy==ey)
{
if(oans+1<answer1)fz(oans+1,o1,o2);
else if(oans+1==answer1&&o1+o2<answer4)fz(oans+1,o1,o2);
else if(oans+1==answer1&&o1+o2==answer4&&o1<answer2)fz(oans+1,o1,o2);
}
}
}
}
if(o2+1<=c2&&i<4)//用瞬移
{
int xx=ox+dx[i]*d,yy=oy+dy[i]*d;
if(check(xx,yy)&&!z[xx][yy])
{
if(b[xx][yy])
{
if(o1+1<=c1&&!c[xx][yy][o1+1][o2+1])
{
c[xx][yy][o1+1][o2+1]=1;
p[++tail]=(node){
xx,yy,o1+1,o2+1,oans+1};
tail%=100000000;
if(xx==ex&&yy==ey)
{
if(oans+1<answer1)fz(oans+1,o1+1,o2+1);
else if(oans+1==answer1&&o1+1+o2+1<answer4)fz(oans+1,o1+1,o2+1);
else if(oans+1==answer1&&o1+1+o2+1==answer4&&o1+1<answer2)fz(oans+1,o1+1,o2+1);
}
}
}
else
{
if(!c[xx][yy][o1][o2])
{
c[xx][yy][o1][o2+1]=1;
p[++tail]=(node){
xx,yy,o1,o2+1,oans+1};
tail%=100000000;
if(xx==ex&&yy==ey)
{
if(oans+1<answer1)fz(oans+1,o1,o2+1);
else if(oans+1==answer1&&o1+o2+1<answer4)fz(oans+1,o1,o2+1);
else if(oans+1==answer1&&o1+o2+1==answer4&&o1<answer2)fz(oans+1,o1,o2+1);
}
}
}
}
}
}
}
return;
}
int main()
{
scanf("%d%d%d%d%d",&n,&m,&c1,&c2,&d);
for(int i=1;i<=n;i++)//输入
for(int j=1;j<=m;j++)
{
cin>>s;
if(s[0]=='S')p[1]=(node){
i,j,0,0},c[i][j][0][0]=1;
else if(s[0]=='T')ex=i,ey=j;
else if(s[0]!='.')//预处理
{
int len=s.size(),sum=0;
z[i][j]=1;
for(int k=0;k<len;k++)
sum=sum*10+s[k]-48;
for(int x=max(1,i-sum);x<=min(n,i+sum);x++)
for(int y=max(1,j-sum);y<=min(m,j+sum);y++)
if(abs(i-x)+abs(j-y)<sum)
b[x][y]=1;
}
}
bfs();
if(answer1==100000)printf("-1");
else printf("%d %d %d",answer1,answer2,answer3);
return 0;
}