前置知识
平面直角坐标系
x
A
=
x
B
x_A=x_B
xA=xB时,若(
y
A
>
y
B
y_A>y_B
yA>yB),
A
B
=
y
A
−
y
B
AB = y_A - y_B
AB=yA−yB,反之亦然。
y
A
=
y
B
y_A=y_B
yA=yB时,同理。
解题思路
在题目描述中,有这样一句话:
注意:捷径必须是直线。
所以,起点终点坐标要么
x
x
x坐标,要么
y
y
y坐标相同
那这道题就变得简单多了。
横纵坐标分别求一次就可以了,找到每一对
x
x
x或
y
y
y坐标相同的点,找到其中的最短距离即可。
注意:不能出现本来就可以由起点走向终点的“捷径”,即两点相邻(编号差值为1)的情况。
因为需要排序,我们开一个结构体存储每一个点的
x
x
x、
y
y
y坐标和编号
struct node{
int x,y,id;
}s[250050];
排序x坐标
bool cmp1(node a,node b){
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
排序y坐标,同理
接下来,讲代码的最最最最最重点部分,判断点与点之间是否有“捷径”,并存储符合题目的最优“捷径”。
这里结合分析南北方向上的“捷径”的代码注释进行分析
sort(s+1,s+1+n,cmp1);
dista = 250005;
for(int i=1;i<n;i++){
if(s[i].x!=s[i+1].x||abs(s[i].id-s[i+1].id)==1) continue;
//两点x坐标不相同,无法形成捷径
//两点相邻,无法形成捷径
int d,sta,end;//sta 起点 end 终点
char dire;//方向
d = s[i+1].y - s[i].y;//两点距离
if(s[i].id<s[i+1].id){
sta = s[i].id;
end = s[i+1].id;
dire = 'N';
}
else{
sta = s[i+1].id;
end = s[i].id;
dire = 'S';
}
if((d<dista) || (d==dista&&sta<id_start) || (d==dista&&sta==id_start&&end>id_end)){//若符合题目条件,存储
dista = d;//最短距离
id_start = sta;//最优捷径的起点
id_end = end;//最优捷径的终点
direction = dire;//最优捷径的方向
}
}
东西方向上的分析同理,代码与上文代码相似,不再重复分析。
注意:本题在输入字符串时需要做判断是否为“NSEW”字符,否则可能会识别换行符,导致最终结果出错。
ch = getchar();
while(ch<'A'||ch>'Z') ch = getchar();
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
using namespace std;
struct node{
int x,y,id;
}s[250050];
int n,dista,id_start,id_end;
char direction;
bool cmp1(node a,node b){
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
bool cmp2(node a,node b){
return a.y<b.y||(a.y==b.y&&a.x<b.x);
}
int main(){
cin>>n;
s[0].x = s[0].y = s[0].id = 0;
for(int i=1;i<=n;i++){
char ch;
ch = getchar();
while(ch<'A'||ch>'Z') ch = getchar();
if(ch=='N'){
s[i].x = s[i-1].x;
s[i].y = s[i-1].y+1;
}
else if(ch=='S'){
s[i].x = s[i-1].x;
s[i].y = s[i-1].y-1;
}
else if(ch=='W'){
s[i].x = s[i-1].x-1;
s[i].y = s[i-1].y;
}
else if(ch=='E'){
s[i].x = s[i-1].x+1;
s[i].y = s[i-1].y;
}
s[i].id = i;
}
sort(s+1,s+1+n,cmp1);
dista = 250005;
for(int i=1;i<n;i++){
if(s[i].x!=s[i+1].x||abs(s[i].id-s[i+1].id)==1) continue;
int d,sta,end;
char dire;
d = s[i+1].y - s[i].y;
if(s[i].id<s[i+1].id){
sta = s[i].id;
end = s[i+1].id;
dire = 'N';
}
else{
sta = s[i+1].id;
end = s[i].id;
dire = 'S';
}
if((d<dista) || (d==dista&&sta<id_start) || (d==dista&&sta==id_start&&end>id_end)){
dista = d;
id_start = sta;
id_end = end;
direction = dire;
}
}
sort(s+1,s+1+n,cmp2);
for(int i=1;i<n;i++){
if(s[i].y!=s[i+1].y||abs(s[i].id-s[i+1].id)==1) continue;
int d,sta,end;
char dire;
d = s[i+1].x-s[i].x;
if(s[i].id<s[i+1].id){
sta = s[i].id;
end = s[i+1].id;
dire = 'E';
}
else{
sta = s[i+1].id;
end = s[i].id;
dire = 'W';
}
if((d<dista) || (d==dista&&sta<id_start) || (d==dista&&sta==id_start&&end>id_end)){
dista = d;
id_start = sta;
id_end = end;
direction = dire;
}
}
printf("%d %d %d %c",dista,id_start,id_end,direction);
return 0;
}
版权说明:本文为博主原创文章,转载请附上本文链接(https://blog.csdn.net/smart_CZH/article/details/124775117)