YbtOJ 广度搜索课堂过关 例4 荆轲刺秦王【bfs】

题目

在这里插入图片描述


思路

这道题其实思考难度不大,
主要是有一堆细节,码量也很大,
非常考验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;
}

猜你喜欢

转载自blog.csdn.net/Jackma_mayichao/article/details/112915601