2019.1.25ECUST Div3训练赛3,我一道题都没做出来……

本来打算做一道题就跑的,结果第一题都没做出来……

题目

2019-1-25 1900 3 hours ACM ECUST Div3训练赛3
环形地铁
Description

有一环形地铁,一共有n站,编号1−n。

正向行驶地铁会按照1->2->3->⋯->n->1的方向行驶

反向则按照1->n->⋯->3->2->1的方向行驶。

给定相邻两站之间的地铁行驶时间(正向、反向时间相同),现在有m组询问,每次询问从第x站到第y站的最短时间。

Input

输入只有一组数据。

第一行包含两个整数n,m,分别表示地铁站数和询问次数

第二行有n个整数a1,a2,…,an,其中ai表示从第ii站正向行驶到下一站的时间。

接下来m行,每行两个整数x和y,代表询问从第x站到第y站的最短时间。

(1≤n,m,ai≤200000,1≤x,y≤n)

Output

输出m行,第i行输出第i次询问的答案

Sample Input 1

5 2
1 2 3 4 5
1 3
1 5
Sample Output 1

3
5

第一次的WA代码

#include<stdio.h>
int a[200010]={0};
int main(void)
{
	int n,m;//n为地铁站数,m为询问次数 
	int x,y,i=0,sum=0;
	
	scanf("%d %d",&n,&m);
	for(i=0;i<n;i++)
		scanf("%d",&a[i]);//a[i]为从i+1到下一站的时间 
	for(i=0;i<n;i++)
		sum+=a[i];
	
	while(m-->0){
		int d,time1=0,time2=0,time=0;
		scanf("%d %d",&x,&y);//我觉得有必要比较下x,y的大小 
		if(x>y){
			d=y;
			y=x;
			x=d;
		}
		for(x=x-1;x<y-1;x++){
			time1+=a[x];
		}
		time2=sum-time1;
		time=(time1<time2)?time1:time2;
		printf("%d\n",time);
	}
	return 0;
}

在学习群里有人指出要把数据保存再统一输出……
于是有了下面的代码

还是WA╰(‵□′)╯

#include<stdio.h>
int a[200010]={0};
int b[1000000][2];
int main(void)
{
	int n,m,p;//n为地铁站数,m为询问次数 
	int x,y,i=0,sum=0;
	
	scanf("%d %d",&n,&m);
	for(i=0;i<n;i++)
		scanf("%d",&a[i]);//a[i]为从i+1到下一站的时间 
	for(i=0;i<n;i++)
		sum+=a[i];
	p=m;
	for(i=0;p-->0;i++)
		scanf("%d %d",&b[i][0],&b[i][1]);
	
		int j=0;
		while(m-->0){
			int d,time1=0,time2=0,time=0;
	//		scanf("%d %d",&x,&y);//我觉得有必要比较下x,y的大小 
			x=b[j][0];
			y=b[j][1];
			if(x>y){
				d=y;
				y=x;
				x=d;
			}
			for(x=x-1;x<y-1;x++){
				time1+=a[x];
			}
			time2=sum-time1;
			time=(time1<time2)?time1:time2;
			printf("%d\n",time);
			j++;
	}
	return 0;
}

难道还有什么地方没考虑到?
又有人指出数据超出int的范围了,可是把time,time1,time2声明为unsigned int或unsigned long long都还是WA
(;´д`)ゞ

2019年1月25日21点24分

这次终于AC了

#include<stdio.h>
long long a[200010]={0};
long long sum[100010]={0};
int main(void)
{
	int n,m;//n为地铁站数,m为询问次数 
	int x,y,i=0;
	
	scanf("%d %d",&n,&m);
	for(i=0;i<n;i++)
		scanf("%d",&a[i]);//a[i]为从i+1到下一站的时间 
//	for(i=0;i
//		sum+=a[i];
	for(i=1;i<=n;i++)
		sum[i]=sum[i-1]+a[i-1];//sum[i]为从第一站正向行驶到第i+1站的时间,sum[n]为绕行一周的时间 
	
	while(m-->0){
		int d;
		long long time1=0,time2=0,time=0;
		scanf("%d %d",&x,&y);//我觉得有必要比较下x,y的大小 
		if(x>y){
			d=y;
			y=x;
			x=d;
		}
//		for(x=x-1;x
//			time1+=a[x];//嵌套循环会导致超时 
//		}
		time1=sum[y-1]-sum[x-1];
		time2=sum[n]-time1;
		time=(time1<time2)?time1:time2;
		printf("%lld\n",time);
	}
	return 0;
}

所有与time有关的变量声明为long long类型。然后超时了,再把内层循环去掉,改成二位大佬说的那种计算方法就AC了……
大佬们一开始就考虑到什么时间复杂度了?是怎么想出来的?
有必要好好复习数据类型了……
《C Primer Plus》第八章讲的什么啊?看不懂……

2019年1月26日17点19分

你可能感兴趣的:(OJ上的做题经验)