XMU 1350.幸运数组 连续子数组被k整除的个数 STL

http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1350
1350.幸运数组
Time Limit: 2000 MS         Memory Limit: 65536 K
Total Submissions: 221 (61 users)         Accepted: 56 (44 users)
[ My Solution]

Description

doraemon有一个幸运数字K, 并且对于一个数组, 若其和能被K整除, 则称该数组为幸运数组。现在他想知道, 给定一个长度为n且由正整数构成的数组, 它有多少个子数组为幸运数组呢? 其中, 子数组的定义为a[i:j](即a[i] ,a[i + 1], …… ,a[j], 其中1 <= i <= j <= n)

Input

输入的第一行有2个整数n和K(1 <= n <= 50,000, 1 <= K <= 1,000,000,000),分别代表数组的长度和幸运数字,接下来的一行有n个正整数ai(1 <= i <= n, 1 <= ai <= 1,000,000,000), 代表数组的元素。

Output

 输出的一个数字, 代表存在的幸运子数组的个数。

Sample Input

5 6
1 2 3 4 5

Sample Output

2

Hint

2个幸运子数组分别为:
a[1:3] : a[1] + a[2] + a[3] = 6
a[3:5] : a[3] + a[4] + a[5] = 12

Source
doraemon @ xmu

#include<stdio.h>
#include<iostream>
#include<map>
using namespace std;
long long cou;
long long i,j,t,n,k,s;
map<long long,int> mapAns;
map<long long,int>::iterator iter;
int main()
{
    
    while(scanf("%lld %lld",&n,&k)!=EOF)
{
    mapAns[0]=1;
    for(i=1;i<=n;i++)
    {
        scanf("%lld",&t);    
        s+=t;
        if(s>=k)s=s%k;
        mapAns[s]++;
    }
    for(iter=mapAns.begin();iter!=mapAns.end();++iter)
    {
        t=iter->second;
        if(t>1)
        {
            cou+=t*(t-1)/2;
        }
    }
    printf("%lld",cou);
}
    return 0;
}

上面的代码 是看一个大神写的
阿弥陀佛  哎 自己搞的超时   超时的那种 就是把所有和存进 sum 暴力求 

上面大神的思路是:
求出所有的和 存进sum    然后对sum求余   那么余数相同的相减之后为0  也就是说(sumi%k)-(sumj%k)=0  也就是说(sumi-sumj)
%k=0   所以我们只要把所有的sum进行求余 之后如果余数相同 那么2者之间的数就能被k整出(不包括第i个,包括第j个)

所以只要求出所有sum[i]的余数  看某个余数的个数 那么从中取任意2个 其之间的和都能被k整出  另外 要初始化 余数0的个数为1

原因 :对于 1 3 2 4 0 0 2 3 4 0 //这些每个余数的个数    自己可以根据这组数据去分析为什么


算前几项的数字和被11除得余数
得到下面数列
1,5,2,1,6,3,2,5,2,1
所以
三个1出来三组:第2个到第4个的和,第2到第10个的和,第5个到第10个的和
三个2出来三组:第4个到第7个的和,第4到第9个的和,第8个到第9个的和
两个5出来一组:第3个到第8个的和
所以一共只有7组 

你可能感兴趣的:(iterator,input,output)