郑轻周赛(7)复盘,H题

前言:

这个题一开始感觉可以写出来的,样例也过了,但是超时了,比赛前刚学的前缀和,觉得这道题可以用前缀和来解决,但是还是逃不了二重循环遍历,可能刚学还是有点生疏。


题目:

问题 H: 大嘴猫吃金币

时间限制: 1 Sec  内存限制: 128 MB

题目描述
  地面上有排成一条直线的n个金币,金币有不同的价值(甚至是负的),大嘴猫想用它的大嘴来吃这些金币。但是大嘴猫只能张一次嘴,所以它只能吃连续一段的金币。你知道大嘴猫最多能吃多大价值的金币吗?

输入

第一行一个整数n,表示有n个金币 。1 <= n <= 1000000。

输出


接下来n行每行一个整数x,表示金币的价值。x在int范围内。

一行一个整数,表示最多吃下金币的价值。

样例输入 Copy
4
1 2 -1 10
样例输出 Copy
12


分析:

答案分析:从前往后累加,同时维护最⼤值。因为要取sum最⼤的⼀段,所以当加上一个数sum⼩于0时,这一段就停止,让sum=0,跳过这个数从头开始计算下一段的sum。
比如:0  12  -13  14  0    不必考虑负数后面的和加起来为14,比这个负数 -13大,就去取sum为五个数之和,因为这不是最大的,直接跳过-13和前面一段的和为12,只取14,14就是最大的


我的题解:


#include<iostream>
using namespace std;
int n,m,a[1000010];
long long int sum;
int main()
{
	long long int max=-1000000;
	scanf("%d",&n);
	a[0]=0;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",m);
		sum+=m;
		a[i]=sum;//将前i项和储存在数组里,然后作差就可以得到一段距离的金币值
	}	
	for(int i=n;i>=1;i--)//二重循环依次作差找最小值,这步就是超时的原因。。。复杂度是n的平方
	{
		for(int j=i-1;j>=0;j--)
		{
			if(a[i]-a[j]>max)
				max=a[i]-a[j];
		}	
	}	
	printf("%lld",max);
	return 0;
}


答案题解:


#include<iostream>
using namespace std;
const int N = 1e6+5;
typedef long long ll;
int a[N];
ll max(ll a , ll b)
{
    if(a > b)
        return a;
    return b;
}
int main()
{
    int n;
    scanf("%d",&n);
    ll ans = 0 , sum = 0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if(sum + a[i] >= 0)
            sum += a[i];
        else
            sum = 0;
        ans = max(ans,sum);
    }
    printf("%lld\n",ans);
    return 0;
}

总结:

二重遍历循环时最笨也最耗时的,尽量不要用,比赛的时候多分析题意,将问题化简。
前缀和运用不熟练,要多加练习题目。























全部评论

相关推荐

05-12 11:09
已编辑
门头沟学院 后端
已注销:没必要放这么多专业技能的描述。这些应该是默认已会的,写这么多行感觉在凑内容。项目这块感觉再包装包装吧,换个名字,虽然大家的项目基本都是网上套壳的,但是你这也太明显了。放一个业务项目,再放一个技术项目。技术项目,例如中间件的一些扩展和尝试。
点赞 评论 收藏
分享
06-18 16:45
门头沟学院 Java
玩脱了,吊着两家结果两家都不要鼠鼠了,我真想给自己两巴掌。
凉风落木楚山秋:当作是你把这两家公司从地球开除了就行了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务