pat1046Shortest Distance (20)

来源:互联网 发布:java设计模式书籍 编辑:程序博客网 时间:2024/06/06 03:29

题意分析:

(1)给出一个环形公路中几个相邻出口之间的距离,然后任意给出若干对出口,求出这些出口之间最短的距离,(即从一个出口沿着两个方向到达另外一个出口的最短距离)

(2)建议大家画一个示意图,分别求出沿着两个方向遍历到达另外一个出口的距离,然后比较这两个距离

(3)这题坑在第三个案例上面,即使是时间复杂度为O(n)的如此简单算法,PAT的出题人也要在此设坑,简单的遍历都会超时,看来我们不能去遍历求和。如果不能用遍历,那该用什么?仔细想想,貌似在输入结束后,不遍历我们什么也不能做了。那该怎么办?别急!输入完后不能遍历求和,那在输入时呢?出题人总要输入数据的时间吧。因此我们立刻联想到1044题中利用了累积连续和的思想。如果我们存储的是从位置1开始到当前位置的距离,即每次存储的是上一个位置的值+当前相邻出口的距离。这样再计算任意两个出口的距离,直接使用从出口1到出口j的累计距离-出口1到出口i的累计距离,时间复杂度瞬间降到O(1).多么美妙的思路!

可能坑点:

(1)不要简单遍历求和,否则第三个案例超时

(2)另外按照(3)的算法,使用sanf和printf比cin和cout在第三个案例上面有很大差别,分别是11ms和39ms

#include <iostream>#include <algorithm>#include <stdio.h>using namespace std;int main(){    int N,M,i=1,j=0;    scanf("%d",&N);    const int num=N+1;    int distance[num],temp;    distance[0]=0;    while(i<=N)    {        scanf("%d",&temp);        distance[i]=distance[i-1]+temp;        i++;    }    scanf("%d",&M);    int from,to;    while(j<M)    {        scanf("%d %d",&from,&to);        if(from>to)swap(from,to);        int a=distance[to-1]-distance[from-1];        int b=distance[from-1]+distance[N]-distance[to-1];        printf("%d\n",a<b?a:b);        j++;    }    return 0;}


0 0