设为首页 加入收藏

TOP

hdu 4648 Magic Pen 6 多校的一个题目
2014-11-23 21:12:44 来源: 作者: 【 】 浏览:2
Tags:hdu 4648 Magic Pen 一个 题目

题目是说给你N个数再给一个MOD 这N个数的和对MOD取模的值是K问你可以从这N个数中最多删除多少个连续的数使得剩下的数的和模上MOD的结果不变还是K

这题数据范围有点大,不过有O(N)的算法就可以搞定了。

方法 题意转化一下就是: 给出一列数a[1]...a[n],求长度最长的一段连续的数,使得这些数的和能被M整除。 分析:设这列数前i项和为s[i],则一段连续的数的和 a[i]+a[i+1]+...+a[j-1]+a[j]=s[j]-s[i-1],所以这段连续的数的和能被m整除的条件就是 (s[j]-s[i-1]) % m == 0,即 s[j]%m-s[i-1]%m == 0,因此,只需要每一个余数找使s[i]%m等于该余数的最小的i,和s[j]%m等于该余数的最大的j,相减即为最长的连续的数的长度。

代码就比较简单了,只要记录最先出现的不同和得下标就可以很快做出来的,代码精简了sum数组和原数据的数组,可能会有点难懂。。其中v数组的应用是关键,挺好的,这个方法

#include
#include
inline int max(int a,int b) {return a>b  a:b;}
int N,M,a,v[10005],ans,sum,i,pre;//pre是用来记录sum[i-1]的而sum记录的是sum[i]
// v数组的v[i]记录的是第一次出现前缀和为i时其对应的下标,若没出现过就是-1
int main()
{
    while(~scanf("%d%d",&N,&M))
    {
        memset(v,-1,sizeof(v));
        pre=v[0]=sum=ans=0;
        for(i=1;i<=N;++i)
        {
            scanf("%d",&a);
            sum=(pre+a)%M;
            sum=(sum+M)%M;//因为有负数,取模的时候要注意一下的
            if(v[sum]==-1) v[sum]=i;
            ans=max(ans,i-v[pre=sum]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇hdu-4635-Strongly connected-强.. 下一篇HDU 4649 Professor Tian(反状态..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·我的Linux内核学习笔 (2025-12-26 22:21:10)
·如何评价腾讯开源的 (2025-12-26 22:21:07)
·为什么TCP网络编程中 (2025-12-26 22:21:04)
·Python 数据分析与可 (2025-12-26 21:51:20)
·从零开始学Python之 (2025-12-26 21:51:17)