PAT 1046 Shortest Distance

最淳朴的想法,把两个出口,正向走,方向走的距离都累加求和算出来,然后比较输出较小的

#include<iostream>
#include<vector>
using namespace std;

int main()
{
	int num;
	cin >> num;
	int tmp;
	int sum = 0;
	vector<int> vec;
	
	for (int i = 0; i < num; ++i)
	{
		cin >> tmp;
		vec.push_back(tmp);
		sum += tmp;
		
	}
	int num2;
	int exit1;
	int exit2;
	
	int tmpsum1 = 0;
	int tmpsum2 = 0;
	cin >> num2;
	for (int j = 0; j < num2; ++j)
	{
		cin >> exit1 >> exit2;
		if (exit1 > exit2)
			swap(exit1, exit2);
		int k;

		for (k = exit1 - 2; k >= 0; --k)
		{
			tmpsum2 += vec[k];
		}
		for (k = exit2 - 1; k <= num - 1; ++k)
		{
			tmpsum2 += vec[k];
		}
		for (k = exit1 - 1; k < exit2 - 1; ++k)
		{
			tmpsum1 += vec[k];

		}
		cout << (tmpsum1 < tmpsum2 ? tmpsum1 : tmpsum2) << endl;
		tmpsum1 = 0;
		tmpsum2 = 0;

	}

	return 0;
}

效率很低,第三个case超时了,然后改了一下,先累加反向,然后再累加正向距离的 发现tmpsum1 > tmpsum2 的时候就不必再加了

	for (k = exit1 - 1; k < exit2 - 1; ++k)
		{
			tmpsum1 += vec[k];
			if (tmpsum1 >= tmpsum2)
				break;

		}
应该是快了一点,但还是超时,那再减少累加次数, 因为是环的  只累加正向或反方向中的一个,如果tmpsum > half 那另一个方向的总距离 一定较小


int main()
{
	int num;
	cin >> num;
	int tmp;
	int sum = 0;
	vector<int> vec;

	for (int i = 0; i < num; ++i)
	{
		cin >> tmp;
		vec.push_back(tmp);
		sum += tmp;

	}
	int half = sum / 2;
	int num2;
	int exit1;
	int exit2;

	int tmpsum = 0;

	cin >> num2;

	for (int j = 0; j < num2; ++j)
	{
		cin >> exit1 >> exit2;
		if (exit1 > exit2)
			swap(exit1, exit2);
		int k;

		for (k = exit1 - 1; k < exit2 - 1; ++k)
		{
			tmpsum += vec[k];
		

		}	
		if (tmpsum > half)
		tmpsum = sum - tmpsum;
		cout << tmpsum  << endl;
		tmpsum = 0;


	}

	return 0;
}
然而这也没什么卵用,还是超时。。。 其实程序代价最大的地方在于,对于每一个给定的 两个出口  都要去累加求距离总和,这里其实 重复计算了很多次。 就像用递归去算斐波那契数列,时间都浪费在重复的计算上,借鉴求斐波那契数列的解法,哭考虑把计算出来的和存起来,然后看人家是这么写的

#include<stdio.h>
#include<stdlib.h>
using namespace std;
int main(void)
{
	int N,M;
	scanf("%d",&N);
	int i;
	int *dist=(int*)malloc(sizeof(int)*N);
	int sum=0;
	for(i=0;i<N;i++)
	{
		scanf("%d",dist+i);
		sum+=dist[i];
		dist[i]=sum;
	}
	int halfsum=sum/2;


	scanf("%d",&M);
	for(i=0;i<M;i++)
	{
		int d1,d2;
		scanf("%d %d",&d1,&d2);
		if(d1>d2)
		{
			int temp=d2;
			d2=d1;
			d1=temp;
		}
		int d;
		if(d1==1)
			d=dist[d2-2];
		else
			d=dist[d2-2]-dist[d1-2];
		if(d>halfsum)
			d=sum-d;
		if(i!=0)
			printf("\n");
		printf("%d",d);
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值