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 1
Sample Output:
3
10
7



AC

#include<stdio.h> 
#include<iostream>
#include<math.h>
using namespace std;
int arr[100001];
int sum;
int main(){
	scanf ( "%d" , &sum );
	int t = 0,n = 0,a1,a2,dis_1 = 0,dis_2 = 0,temp;
	for ( int i = 1; i <= sum; i++ ){
		scanf("%d",&t);
		arr[i] = t + arr[i-1];
	}
	scanf ( "%d" , &n );
	for ( int i = 1; i <= n; i++ ){
		dis_1 = 0,dis_2 = 0;
		scanf("%d %d",&a1,&a2);
		if ( a1 > a2 ){
			temp = a1;
			a1 = a2;
			a2 = temp;
		}
		dis_1 = arr[a2 - 1] - arr[a1 - 1];
		dis_2 = arr[sum] - dis_1; 
	
		dis_1>dis_2? printf("%d\n",dis_2): printf("%d\n",dis_1);
		
	} 
	return 0;
}
思路:


一开始把两点之间的距离分别存储在数组下标中,例如D1 和 D2之间的距离,就存在arr[1]中,D2和D3的距离存在arr[2]中,依次类推,按题目中给的样例,假设总个数为5个点,那么arr[5]中保存的就是D5和D1 的距离。再给出点之后,按照两种不同方向计算两点之间不同的距离,比较出大小就可以得到结果了。这是第一种比较直观的想法,就是直接将两点距离保存,要计算的时候就按照不同的点来计算就好了。但是这样做存在问题,最后一个测试点会超时,因为可以从代码中看到重复计算的次数太多,计算D1和D2之间的距离时,计算一次,计算D1和D3之间距离时,又需要在计算一边D1和D2的距离,以此类推   重复计算太多。

思路2就是上面AC的代码,这个方法是将距离保存在数组中,但是保存的不是相邻两点距离,而是各个点之间累计的距离。这样做好处有2

第一点好处:避免重复计算

将距离保存在数组中,在计算距离的时候,直接用减法,省去每个点之间的距离相加

好处2:

计算两种距离的之后,第二种只需要用总距离减去第一种距离就可以了。而总距离就保存在数组的最后一个里面。



第一种思路的代码,最后一个测试点超时:

#include<stdio.h> 
#include<iostream>
#include<math.h>
using namespace std;
int arr[100001];
int sum;
/*
	捋一下思路:
	应该存在共性,就是一对数,距离有两种,一种是顺时针,一种是逆时针
	顺时针逆时针所得到的距离大小不定
	无论给出来的数是大数在前还是小数在前,都是以上这两种情况。
	因此可以在做之前调整两个数的位置
	 
*/
int main(){
	scanf ( "%d" , &sum );
	//t是临时输入的距离,用循环。n是后面待计算距离的个数 
	//a1,a2分别是输入的两个坐标 
	int t = 0,n = 0,a1,a2,dis_1 = 0,dis_2 = 0,temp;
	for ( int i = 1; i <= sum; i++ ){
		scanf("%d",&t);
		arr[i] = t;
	}
	scanf ( "%d" , &n );
	for ( int i = 1; i <= n; i++ ){
		dis_1 = 0,dis_2 = 0;
		scanf("%d %d",&a1,&a2);
		/*
			每一对数包含两种情况,长距离和短距离,分别存在dis_1和dis_2中,
			最后要输出最短的距离 
		*/ 
		//定大小,小的放在前面 ,a1小 
		if ( a1 > a2 ){
			temp = a1;
			a1 = a2;
			a2 = temp;
		}
		//第一种距离dis_1   小顺时针---小顺时针其实是逆时针 
		for ( int i = a1; i <= a2 -1; i++ ){
			dis_1 = dis_1 + arr[i];
		} 
		//第二种距离dis_2   大顺时针
		/*
		这里有两种情况,一种是a1是1的时候,这种情况加到a5就不再循环
		第二种情况:当a1比1大的时候,需要 从1开始继续循环到小的-1 ,分为两段计算 
		*/ 
		//无论第一种第二种,这一段是必须算的距离 
		for ( int i = a2; i <= sum; i++ ){
				dis_2 = dis_2 + arr[i];
			}
		for ( int i = 1; i<= a1 - 1; i++ ){
				dis_2 = dis_2 + arr[i];
			}
		//第一种 	
		/* 
		if ( a1 = 1 ){
			dis_2 = dis_2; 
		}
		
		//第二种 
		else{
			
		}
		*/
		dis_1>dis_2? printf("%d\n",dis_2): printf("%d\n",dis_1);
		
	} 
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值