关于算法-数据结构:PAT甲级1046-Shortest-Distance

6次阅读

共计 797 个字符,预计需要花费 2 分钟才能阅读完成。

题目粗心:

有 N 个结点围成一个圈,相邻两个点之间的间隔已知,且每次只能挪动到相邻点。而后给出 M 个询问,每个询问给出两个数字 A 和 B 即结点编号 (1≤A,B≤N), 求从 A 号结点到 B 号结点的最短距离。

算法思路:

因为这 n 各点组成了一个环,那么 A 到 B 有 2 条门路能够走,咱们就假设依照输出的方向为顺时针方向,那么应用数组 sum[N+1] 保留 1 点到带一个顶点的间隔,那么依照顺时针方向,任意 2 点 a 和 b(a<b) 的间隔为 sum[b-1]-sum[a-1],该环的长度为 sum[N], 逆时针的间隔为 sum[N]-(sum[b-1]-sum[a-1]), 最终的 2 点之间的间隔为 min(sum[b-1]-sum[a-1],sum[N]-(sum[b-1]-sum[a-1])).

留神点:
1、输出的查问的 2 点 a 和 b,a 有可能大于 b, 须要替换地位
2、如果没有应用 sum 数组保留累计长度的信息,会超时,因为每次都得遍历数组 
提交后果:

AC 代码:
#include<cstdio>
#include<algorithm>

using namespace std;

int main(){
    int N;
    scanf("%d",&N);
    int d[N+1];// d[i] 示意 i 到 i + 1 的间隔,d[N] 示意 N 到 1 的间隔 
    int sum[N+1];// sum[i] 示意从 1 到 i + 1 的间隔,sum[N] 就是一圈的长度 
    for(int i=1;i<=N;++i){scanf("%d",&d[i]);
        sum[i] = sum[i-1]+d[i];
    }
    int M;
    scanf("%d",&M);
    for(int i=0;i<M;++i){
        int a,b;
        scanf("%d %d",&a,&b);
        if(a>b){
            int c = a;
            a = b;
            b = c;
        }
        int dist = sum[b-1]-sum[a-1];
        printf("%d\n",min(dist,sum[N]-dist));
    }
    return 0;
} 
正文完
 0