蓝桥杯_历届试题 k倍区间
2018-03-27 19:17
281 查看
问题描述 给定一个长度为N的数列,A1, A2, ... AN,如果其中一段连续的子序列Ai, Ai+1, ... Aj(i <= j)之和是K的倍数,我们就称这个区间[i, j]是K倍区间。
你能求出数列中总共有多少个K倍区间吗?输入格式 第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含一个整数Ai。(1 <= Ai <= 100000)输出格式 输出一个整数,代表K倍区间的数目。样例输入5 2
1
2
3
4
5样例输出6数据规模和约定 峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
注意:
main函数需要返回0;
只使用ANSI C/ANSI C++ 标准;
不要调用依赖于编译环境或操作系统的特殊函数。
所有依赖的函数必须明确地在源文件中 #include <xxx>
不能通过工程设置而省略常用头文件。
提交程序时,注意选择所期望的语言类型和编译器类型。
这个题在之前的一次训练赛上做过一次,记得当时已经对前缀和进行了取余,但是后面的那一小点点实在就是没有想出来,这次突然又在蓝桥杯中看到了这个题,很是愉快的就把后面的最后一点写了出来。
我们首先要知道前缀和,就是:sum[1] = a[1];
sum[2] = a[1] + a[2];
sum[3] = a[1] + a[2] + a[3];
......这样我们就可以携写成:
你能求出数列中总共有多少个K倍区间吗?输入格式 第一行包含两个整数N和K。(1 <= N, K <= 100000)
以下N行每行包含一个整数Ai。(1 <= Ai <= 100000)输出格式 输出一个整数,代表K倍区间的数目。样例输入5 2
1
2
3
4
5样例输出6数据规模和约定 峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
注意:
main函数需要返回0;
只使用ANSI C/ANSI C++ 标准;
不要调用依赖于编译环境或操作系统的特殊函数。
所有依赖的函数必须明确地在源文件中 #include <xxx>
不能通过工程设置而省略常用头文件。
提交程序时,注意选择所期望的语言类型和编译器类型。
这个题在之前的一次训练赛上做过一次,记得当时已经对前缀和进行了取余,但是后面的那一小点点实在就是没有想出来,这次突然又在蓝桥杯中看到了这个题,很是愉快的就把后面的最后一点写了出来。
我们首先要知道前缀和,就是:sum[1] = a[1];
sum[2] = a[1] + a[2];
sum[3] = a[1] + a[2] + a[3];
......这样我们就可以携写成:
sum[i] = a[i] + sum[i-1];我们对sum进行取K的余数运算,那么我们得到的就是就在区间[0,k)之间,我们称取余之后的数组为num数组,最后最重要的一小点就是:我们发现num数组中的每两个相同数字之间的区间,这个区间的和就是一个K的倍数,比如:我们对3进行取余,sum数组是[0,1,2,6,10,15],num数组是[0,1,0,0,1,0];我们发现在两个1之间的数组就是在求和之后,他们对于3的余数是相等的,那么这个区间之见一定差的就是3的相应的倍数了。这样我们就理解了,这个题的做法了。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <queue> #include <vector> #include <set> #define ll long long using namespace std; const int MAXN = 100100; ll N,K; ll a[MAXN]; ll sum[MAXN]; ll num[MAXN]; //我们首先要进行求和,然后对每一项求和进行取余,然后我们会会发现非0的相同的数之间的区间就是k的倍数 int main() { scanf("%I64d%I64d",&N,&K); memset(sum,0,sizeof(sum)); memset(num,0,sizeof(num)); for(int i =1;i <= N;i ++) { scanf("%I64d",&a[i]); sum[i] = (a[i] + sum[i-1]) % K; } for(int i = 0;i <= N;i ++) { num[sum[i]] ++; } ll ans =0 ; for(int i = 0;i <K;i++) { ans += (num[i]-1)*num[i]/2; } printf("%I64d\n",ans); return 0; }
相关文章推荐
- 蓝桥杯 历届试题 连号区间数 解题报告
- 蓝桥杯-历届试题-连号区间数
- 蓝桥杯 历届试题 K倍区间数(C语言)
- 蓝桥杯 历届试题 连续区间数----------------------C语言——菜鸟级
- 蓝桥杯历届试题——连号区间数
- 【蓝桥杯】历届试题 连号区间数(运行超时)
- 蓝桥杯 历届试题 k倍区间(同余定理、前缀和、组合)
- 连号区间数 蓝桥杯历届试题
- 蓝桥杯历届试题之连号区间
- 蓝桥杯 - 连号区间数 (历届试题!)
- 蓝桥杯 历届试题 连号区间数
- 蓝桥杯 历届试题 k倍区间
- 蓝桥杯 历届试题 连号区间数
- 蓝桥杯 历届试题 连号区间数
- 蓝桥杯, 历届试题 连号区间数 (暴力)
- 蓝桥杯练习系统历届试题 连号区间数
- 蓝桥杯 历届试题 连号区间数
- 蓝桥杯 历届试题 7.连号区间数
- 历届试题 连号区间数 (蓝桥杯)
- 蓝桥杯 历届试题 连号区间数