[Ybtoj High-Efficiency Advanced 1.5] [Wide Search] Jing Ke assassinated the King of Qin

[Ybtoj High-Efficiency Advanced 1.5] [Wide Search] Jing Ke assassinated the King of Qin

Insert picture description here
Insert picture description here
Insert picture description here


Problem-solving ideas

Preprocessing
The monitoring range of soldiers can be used as an
example. The monitoring range of soldiers is 3, as shown
Insert picture description here
in the figure . The starting point that can be seen in each line is +1, and the first one that cannot be seen is -1.
Finally, all ranges are calculated by prefix

Wide search
can take four to eight directions has been the direction of Teleport
next moves a total of 12 kinds of
four-dimensional marks in the current grid has not passed
the number of coordinates, and teleport and stealth
if at the time the soldiers could be seen, the use of stealth
when the current The number of steps is larger than the known answer, you can skip
the restrictions on attention teleport and invisibility


Code

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct lzf{
    
    
	int x,y,s,w,b;
}q[7001000];
struct lt{
    
    
	int x,y;
}o;
string c;
int n,m,c1,c2,d,zx,zy,ans=-1;
int fx[13]={
    
    0,1,1,0,-1,-1,-1,0,1,0,0,0,0};  //移动的行
int fy[13]={
    
    0,0,1,1,1,0,-1,-1,-1,0,0,0,0};  //移动的列
int fw[13]={
    
    0,0,0,0,0,0,0,0,0,1,1,1,1};  //使用瞬移的次数
int p[362][362][16][16],b[362][362],a[362][362];
void bfs()
{
    
    
	 int h=0,t=1;
	 while (h<t)
	 {
    
    
	 	   h++; 
	 	   if (q[h].b+1>ans&&ans!=-1) continue;  //当前步数大于已知答案
	 	   for (int i=1;i<=12;i++)
	 	   {
    
    
	 	       int xx=q[h].x+fx[i],yy=q[h].y+fy[i],xy=q[h].w+fw[i],ys=q[h].s; 
			   if (xx<1||xx>n||yy<1||yy>m||xy>c2||b[xx][yy]==1) continue;  //不能走,或瞬移超过限制,或有士兵
			   if (a[xx][yy]>0) ys++;  //被士兵看到
			   if (ys>c1||p[xx][yy][xy][ys]) continue;  //走过或隐身超限制
			   q[++t]=(lzf){
    
    xx,yy,ys,xy,q[h].b+1}; 
			   p[xx][yy][xy][ys]=1;  //入队,标记
			   if (xx==zx&&yy==zy)
			   {
    
    
			   	  if ((ans==-1)||(q[t].b<ans)||(q[t].b==ans&&o.x+o.y>xy+ys)||(q[t].b==ans&&o.x+o.y==xy+ys&&o.y>ys))  //更新答案
			   	  {
    
    
			   	  	 ans=q[t].b; 
			   	  	 o.x=xy;
			   	  	 o.y=ys;
				  }
			   }
		   }
	 }
	 if (ans==-1) 
	 {
    
    
	    cout<<-1;
	    return;
	 }
	 cout<<ans<<" "<<o.y<<" "<<o.x<<endl;
}
int main()
{
    
    
	scanf("%d%d%d%d%d",&n,&m,&c1,&c2,&d);
	fx[9]=d,fy[10]=d,fx[11]=-d,fy[12]=-d;  //使用瞬移移动的变化
	for (int i=1;i<=n;i++)
	{
    
    
	    for (int j=1;j<=m;j++)
	    {
    
    
			      cin>>c; 
			      if (c==".") continue;
	    	      if (c=="S")
	    	      {
    
    
	    		     q[1].x=i,q[1].y=j,p[i][j][0][0]=1;
	    		     continue;
		   	      }
			      if (c=="T")
			      {
    
    
				     zx=i,zy=j;
				     continue;
			      }
			      int x=0;
			      for (int k=0;k<c.size();k++) x=x*10+c[k]-48; 
			      x--; 
			      b[i][j]=1; 
			      for (int k=max(1,i-x);k<=min(n,i+x);k++)
			      {
    
    
			      	  int l=max(1,j-x+abs(i-k));
			      	  int r=min(m,j+x-abs(i-k));
			      	  a[k][l]++,a[k][r+1]--; 
				  }  //查分预处理
		}
    }
    for (int i=1;i<=n;i++)
		for (int j=1;j<=m;j++)
		    a[i][j]+=a[i][j-1];  //前缀和
	bfs();
	return 0;
}

Guess you like

Origin blog.csdn.net/qq_45621109/article/details/112918252