PTA航船
题目描述
航船游戏中,风向每个单位时间会改变一次,每次航船可以选择顺风前行一个单位距离,也可以选择原地不动。游戏时长为 t,请你计算从起点出发,最终到达终点所需要的最少移动次数。如果游戏结束也到达不了终点,则输出-1。
输入格式
第一行包括一个正整数 t(1<=t<=100000)。
第二行为起点坐标(x1 , y1)。
第三行为终点坐标(x2 , y2)。
接下来 t 行,每行输入一个单词,表示风向 。
输出格式
输出为一个整数,为到达终点所需移动的最少步数;如果无法到达,输出-1。
输入样例
在这里给出一组输入。例如:
5
1 1
2 2
east
north
west
west
north
输出样例
在这里给出相应的输出。例如:
2
思路
- 第一层:用宽度优先搜索加队列,超时+答案错误
- 第二层:可由曼哈顿距离联想出一个特判,当最大可能步数小于两点的距离差时,绝不可能到达终点。就比如硬要让一个轻骑兵跑完整个戈壁滩一样。(骗了10分)
- 第三层:由于题目问的是最少走几步到达,而不是第几步到达,由贪心的思想可得,可大胆的不去计算与目的地方向相反的步数(不要去走冤枉路,浪费精力)
- 第四层:只要某一个或两个方向的步数超过所需的纵向或横向的阈值,即可证明有到达终点的可能性(且答案是固定的,至少这两个字简直就是出题人的恶意所在)。
代码
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;
int ax,ay,bx,by;//起始位置和结束位置的坐标
int n,cnt_n,cnt_w,cnt_e,cnt_s;//各个方向上个数的统计
int find_ans()
{
int sum=0;
//x轴方向上位置的比较
if(ax<bx)//起始位置在终点位置的左侧
{
if(bx-ax>cnt_e)//水平方向距离差比向东走的距离还大
{
return -1;
}
else
sum+=bx-ax;
}
else if(ax>bx)//起始位置在终点位置的右侧
{
if(ax-bx>cnt_w)//水平方向距离差比向西走的距离还大
{
return -1;
}
else
sum+=ax-bx;
}
//y轴方向上位置的比较
if(ay<by)//起始位置在终点位置的下面
{
if(by-ay>cnt_n)//垂直方向距离差比向北走的距离还大
{
return -1;
}
else
sum+=by-ay;
}
else if(ay>by)//起始位置在终点位置的上方
{
if(ay-by>cnt_s)//垂直方向距离差比向南走的距离还大
{
return -1;
}
else
sum+=ay-by;
}
return sum;
}
int main()
{
int i;
string s;
cin>>n;
cin>>ax>>ay>>bx>>by;
for(i=0;i<n;i++)
{
cin>>s;
switch (s[0])//提取首字母,并统计各个方向的个数
{
case 'n':cnt_n++;break;
case 'w':cnt_w++;break;
case 'e':cnt_e++;break;
case 's':cnt_s++;break;
}
}
cout<<find_ans();
return 0;
}
- 伤心地(错误代码)
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int ax,ay,bx,by;
int dir[100005];
int pos=0;
int flag=0;
int dx[4]={0,0,-1,1};
int dy[4]={1,-1,0,0};
typedef struct{
int cx;
int cy;
int co;
}node;
int bfs()
{
queue<node > q;
node node_1;
node_1.cx=ax;
node_1.cy=ay;
node_1.co=0;
q.push(node_1);
while(!q.empty())
{
node cur_node=q.front();
q.pop();
if(cur_node.cx+dx[dir[cur_node.co]]==bx&&cur_node.cy+dy[dir[cur_node.co]]==by)
return cur_node.co+1;
node new_node;
new_node.cx =cur_node.cx+dx[dir[cur_node.co]];
new_node.cy =cur_node.cy+dy[dir[cur_node.co]];
new_node.co =cur_node.co+1;
q.push(new_node);
new_node.cx =cur_node.cx;
new_node.cy =cur_node.cy;
new_node.co =cur_node.co+1;
q.push(new_node);
}
return -1;
}
int main()
{
int n;
int i;
string s;
cin>>n;
cin>>ax>>ay>>bx>>by;
if(n<(bx-ax)+(by-ay))
{
cout<<-1;
return 0;
}
for(i=0;i<n;i++)
{
cin>>s;
switch (s[0]){
case 'n':dir[pos++]=0;break;
case 's':dir[pos++]=1;break;
case 'w':dir[pos++]=2;break;
case 'e':dir[pos++]=3;break;
}
}
int answer=bfs();
cout<<answer;
return 0;
}
感谢
感谢wxdl的指导