zoukankan      html  css  js  c++  java
  • NOIP 2013 普及组 小朋友的数字

    描述

    有 n 个小朋友排成一列。每个小朋友手上都有一个数字,这个数字可正可负。规定每个小朋友的特征值等于排在他前面(包括他本人)的小朋友中连续若干个(最少有一个)小朋友手上的数字之和的最大值。
    作为这些小朋友的老师,你需要给每个小朋友一个分数,分数是这样规定的:第一个小朋友的分数是他的特征值,其它小朋友的分数为排在他前面的所有小朋友中(不包括他本人),小朋友分数加上其特征值的最大值。
    请计算所有小朋友分数的最大值,输出时保持最大值的符号,将其绝对值对 p 取模后输出。

    格式

    输入格式

    第一行包含两个正整数 n、p,之间用一个空格隔开。
    第二行包含 n 个数,每两个整数之间用一个空格隔开,表示每个小朋友手上的数字。

    输出格式

    输出只有一行,包含一个整数,表示最大分数对 p 取模的结果。

    样例1

    样例输入1

    5 997
    1 2 3 4 5
    
    

    样例输出1

    21
    
    

    样例2

    样例输入2

    5 7
    -1 -1 -1 -1 -1
    
    

    样例输出2

    -1
    
    

    限制

    每个测试点1s。

    提示

    样例1说明:
    小朋友的特征值分别为 1、3、6、10、15,分数分别为 1、2、5、11、21,最大值 21 对 997 的模是 21。
    样例2说明:
    小朋友的特征值分别为-1、-1、-1、-1、-1,分数分别为-1、-2、-2、-2、-2,最大值 -1 对 7 的模为-1,输出-1。
    对于 50%的数据,1 ≤ n ≤ 1,000,1 ≤ p ≤ 1,000所有数字的绝对值不超过 1000;
    对于 100%的数据, 1 ≤ n ≤ 1,000,000, 1 ≤ p ≤ 10 ^ 9 ,其他数字的绝对值均不超过 10 ^ 9 。


    这道题最后二十分不好拿啊。。。。

    感觉比赛场上我肯定拿不到。。。(逃

    前80分没什么难度吧特征值和分数都可以O(N)算出

    最后注意到(然而我并没有注意到QAQ)分数在记算的过程中可能会爆longlong

    所以得边算边取模

    然而取模就无法比较最大值了

    所以不能直接max

    注意到从第二个人开始分数是不下降的

    所以对于i>=3

    if(b[i-1]>0) c[i]=c[i-1]+b[i-1];
    else c[i]=c[i-1];

    (b[ ]特征值, c[ ]分数)

    这样就可以运算过程中取模了

    因为不需要比较最大值

    但最后还得跟c[1]比较

    注意到c[1]不会超过1e9

    所以如果计算中c[i]超过1e9

    就肯定大于c[1]了,就可以取模了

    而如果没有大于1e9,也就不会爆longlong

    所以也不需要取模

    这样就拿到了最后20分。。。

    还是得仔细审数据范围啊。。。

    #include<cstdio>
    const int N=1000008,K=1e9+100;
    int a[N];
    long long b[N],c[N];
    int main()
    {
    	int n;long long mod;
    	scanf("%d %lld",&n,&mod);
    	for(int i=1;i<=n;i++)
    	scanf("%d",&a[i]);
    	long long  max=-2*1e15,sum=0;
    	for(int i=1;i<=n;i++)
    	{
    		sum+=a[i];
    		max=max>sum?max:sum;
    		b[i]=max;
    		if(sum<0)	sum=0;
    	}
    	c[1]=b[1];c[2]=b[1]+b[1];
    	bool f=0;
    	for(int i=3;i<=n;i++)
    	{
    		if(b[i-1]>0)	c[i]=c[i-1]+b[i-1];
    		else c[i]=c[i-1];
    		if(c[i]>K)		f=1,c[i]%=mod;
    	}
    	if(f)		printf("%lld
    ",c[n]%mod);
    	else		printf("%lld",(c[1]>c[n]?c[1]:c[n])%mod);
    	return 0;
    }

  • 相关阅读:
    Java实现 LeetCode 27 移除元素
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 24 两两交换链表中的节点
    Java实现 LeetCode 24 两两交换链表中的节点
    Java实现 LeetCode 24 两两交换链表中的节点
  • 原文地址:https://www.cnblogs.com/Brian551/p/7353004.html
Copyright © 2011-2022 走看看