蓝桥杯每日一题2023.11.11

题目描述

"蓝桥杯"练习系统 (lanqiao.cn)

题目分析

对于此题首先想到的是暴力分析,使用前缀和,这样方便算出每一区间的大小,枚举长度和其实位置,循环计算出所有区间的和进行判断,输出答案。

非满分暴力写法:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
typedef long long ll;
ll a[N], s[N], n, k, ans;
int main()
{
	cin >> n >> k;
	for(int i = 1; i <= n; i ++)
	{
		cin >> a[i];
		s[i] = s[i - 1] + a[i];
	}
	for(int i = 1; i <= n; i ++)//长度 
	{
		for(int j = 1; j <= n; j ++)//起始位置 
		{
			int r = j + i - 1;
			if(r <= n)
			{
				int q = s[r] - s[j - 1];
				if(q % k == 0)ans ++;
			} 
		} 
	}
	cout << ans;
	return 0;
}

以上两重循环超时,我们把其改为一重循环

由s[r] - s[l - r] % k == 0 推出 s[r] % k == s[l - 1] % k

故我们需要固定循环右端点,确定下与此点对应相同的之前点的个数,有多少个一样的点就说明出现了多少个k倍区间,将个数加入答案即可

此点对应的值 + 1,故为cnt[s[i] % k] ++

满分代码如下:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
typedef long long ll;
ll a[N], s[N], cnt[N], n, k, ans;
int main()
{
	cin >> n >> k;
	for(int i = 1; i <= n; i ++)
	{
		cin >> a[i];
		s[i] = s[i - 1] + a[i];
	}
	cnt[0] = 1;//注:s[0] % k == 0,故循环之前为0的数已经有一个 
	for(int i = 1; i <= n; i ++)
	{
		ans += cnt[s[i] % k];
		cnt[s[i] % k] ++;
	}
	cout << ans;
	return 0;
}
相关推荐
json{shen:"jing"}3 小时前
字符串中的第一个唯一字符
算法·leetcode·职场和发展
追随者永远是胜利者3 小时前
(LeetCode-Hot100)15. 三数之和
java·算法·leetcode·职场和发展·go
马士兵教育5 小时前
程序员简历如何编写才能凸显出差异化,才能拿到更多面试机会?
开发语言·后端·面试·职场和发展·架构
hqyjzsb6 小时前
企业培训ROI深度分析:如何将CAIE认证的显性与隐性成本纳入投资回报率模型
人工智能·考研·职场和发展·创业创新·学习方法·业界资讯·改行学it
programhelp_7 小时前
特斯拉 MLE 超详细面经 + 避坑
数据结构·人工智能·算法·面试·职场和发展
List<String> error_P8 小时前
Python蓝桥杯常考知识点-模拟
开发语言·python·蓝桥杯
追随者永远是胜利者12 小时前
(LeetCode-Hot100)4. 寻找两个正序数组的中位数
java·算法·leetcode·职场和发展·go
我命由我1234512 小时前
Photoshop - Photoshop 工具栏(61)切片工具
学习·ui·职场和发展·求职招聘·职场发展·学习方法·photoshop
我命由我1234513 小时前
Photoshop - Photoshop 工具栏(62)切片选择工具
学习·ui·职场和发展·求职招聘·职场发展·学习方法·photoshop
追随者永远是胜利者14 小时前
(LeetCode-Hot100)5. 最长回文子串
java·算法·leetcode·职场和发展·go