2013NOIP普级组-- 小朋友的数字

题目链接:

https://www.luogu.org/problemnew/show/P1982

       很显然,这是一个最大字段和问题,但是要注意的是在算每个小朋友的分数的时候是会爆longlong的,我们注意到小朋友的特征值和分数是递增的,手动进行模拟特征值和分数可以得出:

      如果要求的小朋友的分数的上一个小朋友的特征值是大于等于零的,那么往后的时候每一个小朋友的分数都为他上一个小朋友的分数加上特征值。否则的话,这个小朋友的分数为第一个小朋友的分数加上特征值。

      所以答案要么是第一个小朋友的分数,要么是最后一个小朋友的分数,我们最后只要对比第一个小朋友的分数和最后一个小朋友的分数就行,但是问题来了,因为分数的大小有可能会爆longlong,所以我们在计算的时候会一边取模一边计算,如此这般的话就无法比较取模之前的分数和第一个分数的大小了, 但是我们注意到第一个分数的大小是不会超过1e9的,所以每当第i个小朋友的分数大于1e9的时候就说明答案是最后一个的分数。

代码:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <stdio.h>
using namespace std;
const int inf=1e6+7;
typedef long long ll;
ll arr[inf];
ll special[inf];
ll score[inf];

ll max(ll a,ll b)           //先尝试不用取余函数。
{
	if(a>b)return a;
	else
		return b;
}

int main()
{
	ll n,q;
	scanf("%lld %lld",&n,&q);
	for(int i=0;i<n;++i)
		scanf("%lld",&arr[i]);
	special[0]=arr[0];			//这里应该是关键所在。
	score[0]=special[0];         //都是从零开始的。

	ll sum=arr[0];
	ll themax=arr[0];
    int lastflag=0;
	int flag=0;
	if(arr[0]>=0)flag=1;
	for(int i=1;i<n;++i)
	{
		if(sum>0)
		{
			sum+=arr[i];
		}
		else
		{
			sum=arr[i];
		}
		themax=max(themax,sum);
		special[i]=themax;		//特征值。还不至于爆longlong,
        if(special[i-1]>=0)     //就是这里。重点重点!!!!!!!!!
        {
            flag=1;
        }
        ll temptemp=score[i-1]+special[i-1];
		if(flag==0)
        {
            score[i]=special[0]+score[0];
        }
		else
        {
            if(temptemp>=score[0])lastflag=1;
            if(temptemp>1000000000)
            {
                lastflag=1;
                temptemp%=q;
            }
            score[i]=temptemp;
        }
	}
	if(flag==0||lastflag==0)
    {
        if(score[0]<0)
        {
            if(score[0]%q!=0)
                printf("-");
            score[0]*=(-1);
        }
        printf("%lld\n",score[0]%q);
    }
    else
    {
        if(score[n-1]<0)
        {
            if(score[n-1]%q!=0)
                printf("-");
            score[n-1]*=-1;
        }
        printf("%lld\n",score[n-1]%q);
    }
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NOIP(全国青少年信息学奥林匹克竞赛)是中国举办的一项顶尖竞赛,旨在选拔和培养青少年信息学人才。CSP(计算机科学与编程竞赛)是NOIP的初赛,包括提高普及两个不同难度的竞赛。 从1995年到2021年,CSP提高复赛试题持续不断地推陈出新。试题的难度和内容与时俱进,反映了信息科技和计算机学科的发展趋势。 这些试题涵盖了计算机科学与编程的各个领域,如数据结构、算法设计与分析、图论、动态规划等。这些题目不仅要求考生熟悉编程语言,还需要考生具备分析问题、设计算法、优化程序的能力。因此,参加CSP的考生需要有扎实的计算机基础知识和编程技巧。 CSP试题的设计目标是培养学生的创新思维、动手能力和问题解决能力。试题往往是实际问题的抽象化,考生需要将问题拆解、建模,并设计出适用的算法和程序来解决。这种综合应用的能力培养能够提高学生的实践能力和创新能力,为他们今后的学习和工作打下坚实的基础。 此外,CSP试题还注重培养学生的团队合作精神和竞技意识。复赛试题通常要求考生在限定时间内完成,这要求考生在有限的时间内高效地协作和解决问题。 总之,NOIP CSP提高复赛试题的不断更新和提高,以及其注重培养学生的综合能力,使得参加这项竞赛的学生能够更好地理解和应用计算机科学知识,为他们日后的学习和发展打下良好的基础。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值