题意分析:
(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;
}