今天继续巩固了宽搜,用数组实现队列,以下两题前天看到的时候一点头续都没有,今天读完题就有思路了,就是调试的时候问题有点多,写码半小时,找bug一小时。

我们用读先pop数组,如果这个数没有入栈,我们就一直push,直到入栈,并且释放出来,如果已经入栈,并且pop出来这个数与之不相等,那么不符合题意
#include<stdio.h>
int tail,t,t1;
int a[100000],b[100000],c[100000];
void pop()
{
a[tail]=0;
tail--;
}
void push(int b)
{
tail++;
a[tail]=b;
}
int main()
{
int m,n;
scanf("%d",&m);
while(m--)
{
int d[100000]={0};
t1=0;
tail=-1;
t=0;
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&b[i]);
for(int i=0;i<n;i++) scanf("%d",&c[i]);
push(b[t]);
d[b[t]]=1;
t++;
while(t1<n)
{
if(d[c[t1]]==0)
{
push(b[t]);
d[b[t]]=1;
t++;
}
else
{
if(a[tail]==c[t1])
{
pop();
t1++;
}
else
{
printf("No\n");
break;
}
}
}
if(t1==n) printf("Yes\n");
}
return 0;
}

比一般的迷宫多了个传送装置,因为是找最短,所以用BFS,走过的草地标记为-1,因为重复走是没有意义的,但是有一个注意的地方,那就是因为奶牛经过传送点的时候必须使用,所以传送点是可以多次使用的,我们如果要去到第一个传送点的位置,要传送两次,其他的和普通迷宫问题没什么区别,走到传送点时,直接将另一个传送点入列;
#include<stdio.h>
int a[310][310],xy[2][4]={{0,-1,0,1},{1,0,-1,0}};
int b[30][4],head,tail=1;
int c[100000][3];
int main()
{
int m,n,sx,sy,fx,fy,t;
char q;
scanf("%d %d",&m,&n);
for(int i=1;i<=m;i++)
{
getchar();
for(int j=1;j<=n;j++)
{
scanf("%c",&q);
if(q=='#') a[i][j]=1;
else if(q=='.') a[i][j]=0;
else if(q>=65&&q<=90)
{
a[i][j]=q-62;//3-28
if(b[q-62][0]==0)
{
b[q-62][0]=i;
b[q-62][1]=j;
}
else
{
b[q-62][2]=i;
b[q-62][3]=j;
}
}
else if(q=='@')
{
sx=i;
sy=j;
a[sx][sy]=0;
}
else if(q=='=')
{
fx=i;
fy=j;
a[i][j]=2;
}
}
}
c[0][0]=sx;
c[0][1]=sy;
while(head<tail)
{
for(int i=0;i<4;i++)
{
sx=c[head][0]+xy[0][i];
sy=c[head][1]+xy[1][i];
t=a[sx][sy];
if(sx<1||sy<1||sx>m||sy>n) continue;
if(t==1) continue;
if(t==2)
{
printf("%d\n",c[head][2]+1);
break;
}
if(t>2)
{
if(b[t][0]==sx&&b[t][1]==sy)
{
c[tail][0]=b[t][2];
c[tail][1]=b[t][3];
c[tail][2]=c[head][2]+1;
tail++;
}
else
{
c[tail][0]=b[t][0];
c[tail][1]=b[t][1];
c[tail][2]=c[head][2]+1;
tail++;
}
}
if(t==0)
{
c[tail][0]=sx;
c[tail][1]=sy;
c[tail][2]=c[head][2]+1;
a[sx][sy]=-1;
tail++;
}
}
if(t==2) break;
head++;
}
return 0;
}
这题第一次提交的时候运行错误,因为m,n是<=300,而我恰好把数组设为300,0行和0列又没用,所以少了一行,我是万万没想到样例中刚好有300大小的。