荆轲刺秦王
题目链接:荆轲刺秦王
题目描述
解题思路
首先,我们要学会一项很重要的技能:cp(copy&paste)
然后,我们要开始分类讨论:
- 两个技能都不用。
- 只用隐身。
- 只用瞬移。
- 两个技能都用。
这道题其实也就是码量大了亿点而已,思路不是很难。
code
#include<iostream>
#include<cstdio>
#include<cstring>
#define chen using
#define du namespace
#define xiu std
chen du xiu;
const int xn[9]={0,0,1,0,-1,-1,1,-1,1};
const int yn[9]={0,1,0,-1,0,-1,1,1,-1};
int n,m,c1,c2,d,ex,ey;
int ans=0x3f3f3f3f,p,q,flg;
int a[400][400];
int b[400][400];
int v[400][400][20][20];
struct abc{
int x,y,c1,c2,s;
}f[10000000];
int abs(int t)
{
if(t<0)
return -t;
return t;
}
bool bfs()
{
int hd=0,tl=1;
v[f[hd].x][f[hd].y][0][0]=1;
while(hd<tl)
{
hd++;
hd%=10000000;
for(int i=1;i<=8;i++)
{
int x=f[hd].x+xn[i];
int y=f[hd].y+yn[i];
if(x<1||x>n||y<1||y>m)
continue;
if(a[x][y]==0&&b[x][y]==0&&v[x][y][f[hd].c1][f[hd].c2]==0)
{
tl++;
tl%=10000000;
f[tl]=(abc){x,y,f[hd].c1,f[hd].c2,f[hd].s+1};
v[x][y][f[hd].c1][f[hd].c2]=1;
if(x==ex&&y==ey)
{
v[x][y][f[hd].c1][f[hd].c2]=0;
flg=1;
if(f[tl].s<ans)
{
ans=f[tl].s;
p=f[tl].c1;
q=f[tl].c2;
}
if(f[tl].s==ans&&f[tl].c1+f[tl].c2<p+q)
{
p=f[tl].c1;
q=f[tl].c2;
}
if(f[tl].s==ans&&f[tl].c1+f[tl].c2==p+q&&f[tl].c2<q)
{
p=f[tl].c1;
q=f[tl].c2;
}
}
}
if(b[x][y]==1&&a[x][y]==0&&v[x][y][f[hd].c1+1][f[hd].c2]==0&&f[hd].c1+1<=c1)
{
tl++;
tl%=10000000;
f[tl]=(abc){x,y,f[hd].c1+1,f[hd].c2,f[hd].s+1};
v[x][y][f[hd].c1+1][f[hd].c2]=1;
if(x==ex&&y==ey)
{
v[x][y][f[hd].c1+1][f[hd].c2]=0;
flg=1;
if(f[tl].s<ans)
{
ans=f[tl].s;
p=f[tl].c1;
q=f[tl].c2;
}
if(f[tl].s==ans&&f[tl].c1+f[tl].c2<p+q)
{
p=f[tl].c1;
q=f[tl].c2;
}
if(f[tl].s==ans&&f[tl].c1+f[tl].c2==p+q&&f[tl].c2<q)
{
p=f[tl].c1;
q=f[tl].c2;
}
}
}
if(i>4)
continue;
x=f[hd].x+d*xn[i];
y=f[hd].y+d*yn[i];
if(x<1||x>n||y<1||y>m)
continue;
if(b[x][y]==0&&a[x][y]==0&&v[x][y][f[hd].c1][f[hd].c2+1]==0&&f[hd].c2+1<=c2)
{
tl++;
tl%=10000000;
f[tl]=(abc){x,y,f[hd].c1,f[hd].c2+1,f[hd].s+1};
v[x][y][f[hd].c1][f[hd].c2+1]=1;
if(x==ex&&y==ey)
{
v[x][y][f[hd].c1][f[hd].c2+1]=0;
flg=1;
if(f[tl].s<ans)
{
ans=f[tl].s;
p=f[tl].c1;
q=f[tl].c2;
}
if(f[tl].s==ans&&f[tl].c1+f[tl].c2<p+q)
{
p=f[tl].c1;
q=f[tl].c2;
}
if(f[tl].s==ans&&f[tl].c1+f[tl].c2==p+q&&f[tl].c2<q)
{
p=f[tl].c1;
q=f[tl].c2;
}
}
}
if(b[x][y]==1&&a[x][y]==0&&v[x][y][f[hd].c1+1][f[hd].c2+1]==0&&f[hd].c1+1<=c1&&f[hd].c2+1<=c2)
{
tl++;
tl%=10000000;
f[tl]=(abc){x,y,f[hd].c1+1,f[hd].c2+1,f[hd].s+1};
v[x][y][f[hd].c1+1][f[hd].c2+1]=1;
if(x==ex&&y==ey)
{
v[x][y][f[hd].c1+1][f[hd].c2+1]=0;
flg=1;
if(f[tl].s<ans)
{
ans=f[tl].s;
p=f[tl].c1;
q=f[tl].c2;
}
if(f[tl].s==ans&&f[tl].c1+f[tl].c2<p+q)
{
p=f[tl].c1;
q=f[tl].c2;
}
if(f[tl].s==ans&&f[tl].c1+f[tl].c2==p+q&&f[tl].c2<q)
{
p=f[tl].c1;
q=f[tl].c2;
}
}
}
}
}
}
int main()
{
cin>>n>>m>>c1>>c2>>d;
char c;
c=getchar();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
c=getchar();
while(c!=' '&&c!='\n')
{
a[i][j]=a[i][j]*10+c-'0';
c=getchar();
}
if(a[i][j]=='S'-48)
f[1].x=i,f[1].y=j,a[i][j]=0;
if(a[i][j]=='T'-48)
ex=i,ey=j,a[i][j]=0;
if(a[i][j]=='.'-48)
a[i][j]=0;
if(a[i][j]<=15&&a[i][j]>=1)
{
for(int ii=max(1,i-a[i][j]);ii<=min(n,i+a[i][j]);ii++)
for(int jj=max(1,j-a[i][j]);jj<=min(m,j+a[i][j]);jj++)
if(abs(i-ii)+abs(j-jj)<a[i][j]&&a[ii][jj]==0)
b[ii][jj]=1;
}
}
bfs();
if(!flg)
cout<<-1<<endl;
else
printf("%d %d %d\n",ans,p,q);
}