1046 Shortest Distance (20 分)
The task is really simple: given N exits on a highway which forms a simple cycle, you are supposed to tell the shortest distance between any pair of exits.
Input Specification:
Each input file contains one test case. For each case, the first line contains an integer N (in [3,10^ ]), followed by N integer distances D1D2⋯ DN, where Di is the distance between the i-th and the (i+1)-st exits, and DN is between the N-th and the 1st exits. All the numbers in a line are separated by a space. The second line gives a positive integer M (≤10^4), with M lines follow, each contains a pair of exit numbers, provided that the exits are numbered from 1 to N. It is guaranteed that the total round trip distance is no more than 10^7.
Output Specification:
For each test case, print your results in M lines, each contains the shortest distance between the corresponding given pair of exits.
Sample Input:
5 1 2 4 14 9
3
1 3
2 5
4 1
Sample Output:
3
10
7
时间限制
200 ms
内存限制
64 MB
题意:
有N个结点围成一个圈,相邻两个结点的距离已知,求A结点到B结点的最短距离(计算顺时针距离和逆时针距离输出较小者)。
思路1:
int型变量N接收结点数,int型数组num接收各结点的距离(num[1]存放1-2的距离),sum存放一周的路径,int型变量M存放要查询的组数,a,b存放查询的两个结点编号,distance1存放顺时针距离,distance2存放逆时针距离。
外层for循环不断接收结点,里层循环计算顺时针逆时针距离,最后输出最小的距离。
参考代码1:
#include <cstdio>
int main(){
int N;
scanf("%d",&N);
int num[N+1];//存放输入的距离(num[1]代表1-2的距离);
int sum=0;
for (int i=1;i<=N;i++){
scanf("%d",&num[i]);
sum+=num[i];
}
int M;
scanf("%d",&M);
int a,b;
for (int i=0;i<M;i++){
scanf("%d %d",&a,&b);
int distance1=0,distance2=0;
if(a<b){
for (int j=a;j<b;j++){
distance1+=num[j];
distance2=sum-distance1;
}
}
else{
for(int j=b;j<a;j++){
distance1+=num[j];
distance2=sum-distance1;
}
}
if(distance1<distance2) printf("%d\n",distance1);
else printf("%d\n",distance2);
}
return 0;
}
此代码最后一个样例点运行超时,因为在极端情况下,每次查询要遍历整个数组,10^5 次操作,计算距离最多要10^4次操作,在200ms是完成不了的。
思路2:
大体跟思路1一致,只不过用了int型数组distance存储距离,distance[i]代表第一个结点到第i个结点顺时针距离。至于任意两个结点a,b(b>a)间的顺时针距离则是distance[b]-distance[a];
参考代码2:
#include <cstdio>
int main(){
int N;
scanf("%d",&N);
int num[N+1];//存放输入的距离(num[1]代表1-2的距离);
int sum=0;
int distance[N+1];
for (int i=1;i<=N;i++){
scanf("%d",&num[i]);
distance[i]=sum;//distance[i]代表从第1个结点到第i个结点的顺时针距离;
sum+=num[i];
}
int M;
scanf("%d",&M);
int a,b;
for (int i=0;i<M;i++){
int distance1=0,distance2=0;
scanf("%d %d",&a,&b);
if(a<b){
distance1=distance[b]-distance[a];
distance2=sum-distance1;
}
else{
distance1=distance[a]-distance[b];
distance2=sum-distance1;
}
if(distance1<distance2) printf("%d\n",distance1);
else printf("%d\n",distance2);
}
return 0;
}
点评:
①此题属于简单模拟型,英文题意也较好理解,按题意翻译即可。
②注意程序的时间复杂度,O(n^2)是不能满足通过要求的,很容易想到空间换时间的策略,用distance数组存储距离。
③注意题目中表明的N,M范围,不难想到此题可能考查关于时间复杂度优化问题。