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 5 ]), followed by N integer distances D 1 D 2 ⋯ D N , where D i is the distance between the i-th and the (i+1)-st exits, and D N 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一开始用了普通的方法,记录每个点到下个点的距离,然后输入起点和终点,如果起点大于终点,就交换位置,因为这样我们只需要考虑一种情况,然后从st遍历到ed-1,dis1一直循环加dis[j],dis2是反向走的,是先走向最后一个点,然后从最后一个点到第一个点,从第一个点到起点。 但是这样做超时了,所以看了柳神的
#include<iostream> #include<cmath> using namespace std; int main(){ int n; cin>>n; int dis[100005] = {0}; for(int i = 1; i <= n; i++){ cin>>dis[i]; } int k, st, ed; cin>>k; for(int i = 0; i < k; i++){ cin >> st >> ed; int minDis = 0, dis1 = 0, dis2 = 0; if(st > ed) swap(st, ed); for(int j = st; j <= ed - 1; j++){ dis1 += dis[j]; } for(int j = ed; j <= n; j++){ dis2 += dis[j]; } for(int j = 1; j <= st -1; j++){ dis2 += dis[j]; } minDis = min(dis1, dis2); cout<<minDis<<endl; } return 0; }这里用了两点很好的方法都可以借鉴,一个是dis数组记录的是从1号点到第i点的总距离,这样就不用循环加上dis[i]了,只需要dis[ed-1] - dis[st-1]就可以算出两点间的距离,这种数组在子序列中经常用得到(很有用!!) 定义一个sum,算出一个距离后,另一个距离就是sum-哪个距离。然后哪个小就输出哪个,还是要交换st和ed,这样只需要考虑一种情况
#include<iostream> #include<cmath> using namespace std; int main(){ int n; cin>>n; int dis[100005] = {0};//dis[i]存的是从第一个点走到第i+1个点的距离,很多求子序列的都是用这个,一般只需要两个相减,就能求出中间这一段 int sum = 0, temp;//sum存的是总路长,如果要求1-2,两个结果分别是1-2的距离还有sum-1到2的距离 for(int i = 1; i <= n; i++){ cin>>temp; sum += temp; dis[i] = sum; } int k, st, ed; cin>>k; for(int i = 0; i < k; i++){ cin >> st >> ed; int minDis; if(st > ed) swap(st, ed); int d = dis[ed - 1] - dis[st - 1]; minDis = min(d, sum - d); cout<<minDis<<endl; } return 0; }