奇怪的电梯
输入格式
共二行。
第一行为33个用空格隔开的正整数,表示N,A,B(1≤N≤200, 1≤A,B≤N)N,A,B(1≤N≤200,1≤A,B≤N)。第二行为NN个用空格隔开的非负整数,表示K i 。
输出格式
一行,即最少按键次数,若无法到达,则输出-1−1。
输入 #1
5 1 5
3 3 1 2 5
输出 #1
3
代码
#include<iostream>
#include<algorithm>
using namespace std;
int n,a,b,s[1000],book[1000],q[1000];
int main()
{
cin>>n>>a>>b;
int i,xx;
for(i=1;i<=n;i++)
cin>>s[i];
for(i=1;i<=n;i++)
book[i]=-1;
int head=0,tail=1;
q[1]=a;
book[a]=0;
while(head<tail)
{
head++;
for(i=0;i<2;i++)
{
if(i%2==0)
{
xx=q[head]+s[q[head]];
if(xx>=1&&xx<=n&&book[xx]==-1)
{
tail++;
q[tail]=xx;
book[xx]=book[q[head]]+1;
}
}
if(i%2==1)
{
xx=q[head]-s[q[head]];
if(xx>=1&&xx<=n&&book[xx]==-1)
{
tail++;
q[tail]=xx;
book[xx]=book[q[head]]+1;
}
}
}
}
cout<<book[b];
}
小结
用BFS进行搜索,找出第一次到达该楼层所需要的按键次数,在搜索完成后直接输出对应楼层的次数即可;
Meteor Shower S
输入格式
* 第 1 行:单个整数:M
* 2…M+1 行:行 i+1 包含三个空格分隔的整数:Xi、Yi 和 Ti
输出格式
*第1行:Bessie到达安全地点所需的最短时间,如果不可能,则为-1。
输入 #1
4
0 0 2
2 1 2
1 1 2
0 3 5
输出 #1
5
代码
#include<iostream>
#include<algorithm>
using namespace std;
struct step{
int x;
int y;
int s;
}q[250010];
int map[500][500],n,tx,ty,t,nxt[4][2]={{1,0},{-1,0},{0,1},{0,-1}},book[500][500];
int main()
{
int i,j;
for(i=0;i<500;i++)
for(j=0;j<500;j++)
map[i][j]=-1;
cin>>n;
for(i=0;i<n;i++)
{
cin>>tx>>ty>>t;
if(map[tx][ty]==-1)
map[tx][ty]=t;
for(j=0;j<4;j++)
{
if(map[tx+nxt[j][0]][ty+nxt[j][1]]==-1&&tx+nxt[j][0]>=0&&tx+nxt[j][0]<=300&&ty+nxt[j][1]>=0&&ty+nxt[j][1]<=300)
map[tx+nxt[j][0]][ty+nxt[j][1]]=t;
if(map[tx+nxt[j][0]][ty+nxt[j][1]]>0&&map[tx+nxt[j][0]][ty+nxt[j][1]]>=t)
map[tx+nxt[j][0]][ty+nxt[j][1]]=t;
}
}
/*for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
printf("%4d ",map[i][j]);
}
cout<<endl;
}*/
int head=0,tail=1,xx,yy,ss;
q[1].x=0;
q[1].y=0;
q[1].s=0;
book[0][0]=1;
while(head<=tail)
{
head++;
if(map[q[head].x][q[head].y]==-1)
{
cout<<q[head].s;
break;
}
for(i=0;i<4;i++)
{
xx=q[head].x+nxt[i][0];
yy=q[head].y+nxt[i][1];
ss=q[head].s+1;
if(xx<0||yy<0||xx>500||yy>500||ss>=map[xx][yy]&&map[xx][yy]!=-1||book[xx][yy]==1)
continue;
tail++;
q[tail].x=xx;
q[tail].y=yy;
q[tail].s=ss;
book[xx][yy]=1;
}
}
if(head>tail)
cout<<-1;
//cout<<endl;
//for(i=1;i<=tail;i++)
//cout<<q[i].x<<' '<<q[i].y<<' '<<q[i].s<<' '<<endl;
}
小结
这道题有一个十分坑的地方,虽然流星只能砸到300的范围内,但是我们的贝西是可以在这些格点以外的地方活动的,所以会导致有一个样例总是过不了,剩下的就是BFS了,先将每一个流星周围的四个点标记,要优先标记小的,并且可能会有前一颗流星的溅射范围与另外一颗流星重合的情况,也要做一个判断,找到第一个为-1(没有标记)的点就大功告成了。