最短曼哈顿距离(递推+枚举 C++)

最短曼哈顿距离
总时间限制: 1000ms 内存限制: 65536kB
描述
假设两点坐标A(x1,y1),B(x2,y2),两点间的直线距离又叫做欧基里德距离,定义为sqrt((x1-x2)2+(y1-y2)2);两点间的曼哈顿距离被定义为fabs(x1-x2)+fabs(y1-y2)。
G老师准备从曼哈顿这座城市的西北角A点出发,到终点B点,沿途要按顺序经过n-2个旅游景点(起点和终点也算在n里边),n个点的坐标需要你来输入,起点A坐标固定为(0,0),G老师有点累,打算少去1个旅游景点(不能少去起点和终点),请你帮忙,计算出少去哪一个景点可以使得从起点A到终点B的曼哈顿距离最短。
输入
共n+1行
第1行1个正整数n,表示G老师旅行的轨迹点数
后n行,每行两个数,表示该旅游景点的坐标
数据规模:
对于40%的数据满足:3≤n≤1000
对于100%的数据满足:3≤n≤100000,-1000≤xi,yi≤1000
输出
两个整数,用空格隔开
第一个数表示不去哪一个景点的顺序编号(如有多个点不去的曼哈顿距离一样,输出顺序路径中不去的最后1个景点)
第二个数表示不去那个景点之后,起点到终点的最小曼哈顿距离
样例输入

4
0 0
8 3
11 -1
10 0

样例输出

2 14

提示
找出递推式
思路点拔:拿到题目后,我们会发现,想要直接求解不太现实所以,先算出第一个景点与
最后一个景点的曼哈顿距离,然后枚举去掉每个城市后的最短曼哈顿距离,然后算出最小的那
个,就结束了,放心,这道题稍加枚举不会超时的!!

#include<cstdio>
#include<cmath>
using namespace std;
struct mhd //定义结构体,存储每个景点的下标
{
    int x,y;
}s[100005];
int dist(const mhd &a,const mhd &b) //计算曼哈顿距离
{
    return fabs(a.x-b.x)+fabs(a.y-b.y);
}
int main()
{
    int n,sum=0,index=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d %d",&s[i].x,&s[i].y); //输入每个景点的坐标
    }
    for(int i=2;i<=n;i++)
    {
        sum+=dist(s[i-1],s[i]); //算出总共的曼哈顿距离
    }
    int ans=sum;
    for(int i=2;i<n;i++) //计算如果这个景区不去的总曼哈顿距离,然后算出最短的那个,就是结果
    {
        if(sum-dist(s[i-1],s[i])-dist(s[i],s[i+1])+dist(s[i-1],s[i+1])<=ans) 
        //注意:是小于等于不是小于,如果是小于,那么就不能保证输出的是最后一个
        {
            ans=sum-dist(s[i-1],s[i])-dist(s[i],s[i+1])+dist(s[i-1],s[i+1]);
            index=i;//保存是那个景点去掉后曼哈顿距离最短
        }
    }
    printf("%d %d\n",index,ans);  //输出这个去掉的景点与最短曼哈顿距离
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42995099/article/details/81837503