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, 105]), followed by N integer distances D1 D2 ... 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 (<=104), 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 107.
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 1Sample Output:
3 10 7
方案1:采用链表的方式
/** 作者:一叶扁舟 时间:22:04 2017/6/16 思路:最初的想法是,采用双向的循环链表来做,无论顺时针还是逆时针,链表都可以访问,同时可以将所走的路径 给打印出来,但是题目中并没有说要输出所走的路径,所以后来发现用链表更加麻烦了,并且最终时间超时了 在这里只是说提供解决问题的一种方案,虽然这个方案并不完美 */ #include <stdio.h> #include <stdlib.h> #define maxSize 100001 //方法1,使用双向链表 struct Data{ int num;//位置序号 int distance;//顺时针距离 // struct Data *pre;//前驱 struct Data *next; }; //获取最短距离 void getDistance(struct Data *head,int start ,int end,int *result){ struct Data *p = head; int d = 0; //找到start位置 while (p->num != start){ p = p->next; } while (p->num != end){ d = d + p->distance; p = p->next; } *result = d; } //测试结果正确,但是运行超时 int main(){ int N; int testNum; int dis;//控制台中的长度 struct Data *head,*p; struct Data *pCurrent; int sum = 0; head = (struct Data *)malloc(sizeof(struct Data)); pCurrent = head; p = head; scanf("%d",&N); for (int i = 0; i < N; i++){ scanf("%d",&dis); sum += dis; struct Data *temp = (struct Data *)malloc(sizeof(struct Data)); temp->num = i; temp->distance = dis; pCurrent->next = temp; pCurrent = temp; } //形成一个循环链表 pCurrent->next = head ->next; //输入的测试用例组数 scanf("%d", &testNum); int start, end; for (int i = 0; i < testNum; i++){ //计算从strat 到end的距离 scanf("%d%d",&start,&end); int result; if (start > end){ getDistance(head->next, end - 1, start - 1, &result); } else{ getDistance(head->next,start-1,end -1,&result); } //输出结果 if (result < (sum - result)){ printf("%d\n", result); } else{ printf("%d\n", sum - result); } } return 0; }
方案2:采用数组:
/* 作者:一叶扁舟 时间:9:28 2017/6/17 思路:使用该方法,和使用循环链表类似,在pat测试结果是运行结果正确,但是时间超时 */ #include <stdio.h> #include <stdlib.h> #define maxSize 100001 //从start点到end点的距离 void getDistance2(int *data,int N, int start, int end,int *result){ int distance = 0; for (int i = start; i < end; i++){ distance += data[i]; } *result = distance; } int main(){ int N;//定点个数 int testTime;//测试案例的次数 int data[maxSize];//相邻两个定点的距离 int a, b; int sum = 0; scanf("%d", &N); for (int i = 0; i < N; i++){ scanf("%d",&data[i]); sum += data[i]; } scanf("%d",&testTime); for (int i = 0; i < testTime; i++){ scanf("%d%d", &a, &b); int result; if (a > b){ getDistance2(data, N, b - 1, a - 1,&result); } else{ getDistance2(data, N, a - 1, b - 1, &result); } //输出最小距离 if (result < sum - result){ printf("%d\n",result); } else{ printf("%d\n",sum - result); } } system("pause"); return 0; }
方案3:采用静态数组,时间复杂度为O(1),最优解,对于遇到时间差,距离差类似题目都可以采用静态数组的方式,在程序运行之前就将所有的数据都计算好。
/* 作者:一叶扁舟 时间:10:23 2017/6/17 思路:利用静态数组,用一个数组装所有定点到1位置的距离,如果求两点距离直接用两点值相减即可 时间复杂度为O(1) */ #include <stdio.h> #include <stdlib.h> #define maxSize 100001 int main(){ int N; int testTime; int data[maxSize] = { 0 }; int a, b; int dis;//相邻两个定点的距离 int sum = 0; scanf("%d",&N); data[0] = 0; for (int i = 1; i <= N; i++){ scanf("%d",&dis); sum += dis; data[i] = data[i - 1] + dis; } scanf("%d",&testTime); for (int i = 0; i < testTime; i++){ scanf("%d%d",&a,&b); if (a > b){//要保证定点a比定点b的序号要小 int temp = b; b = a; a = temp; } int d = data[b - 1] - data[a - 1]; if (d < sum - d){ printf("%d\n",d); } else{ printf("%d\n",sum - d); } } system("pause"); return 0; }