洛谷[USACO16JAN]子共七

题目描述
Farmer John’s NN cows are standing in a row, as they have a tendency to do from time to time. Each cow is labeled with a distinct integer ID number so FJ can tell them apart. FJ would like to take a photo of a contiguous group of cows but, due to a traumatic childhood incident involving the numbers 1 \ldots 61…6, he only wants to take a picture of a group of cows if their IDs add up to a multiple of 7.

Please help FJ determine the size of the largest group he can photograph.

给你n个数,分别是a[1],a[2],…,a[n]。求一个最长的区间[x,y],使得区间中的数(a[x],a[x+1],a[x+2],…,a[y-1],a[y])的和能被7整除。输出区间长度。若没有符合要求的区间,输出0。

输入输出格式
输入格式:
The first line of input contains N (1 ≤ N ≤ 50,000). The next N
lines each contain the N integer IDs of the cows (all are in the range 0 … … … 1,000,000)
第一行一个整数N 下面有N行,每行一个数

输出格式:
Please output the number of cows in the largest consecutive group whose IDs sum
to a multiple of 7. If no such group exists, output 0.
输出最长的区间大小

输入输出样例
输入样例#1:
7
3
5
1
6
2
14
10
输出样例#1:
5
说明
In this example, 5+1+6+2+14 = 28.

**这道题就比较水 **

最简单的思路是n2把所有情况累加一下再%7判断,不断更新ans。
显然 n = 50,000,这样我们是过不去的,只有70, 那么我们先考虑优化 :
①把第二重循环写成j = i + 1;
②在循环里判断如果i与j的差小于当前答案,就直接continue;
(这和剪枝差不多来着)这样就跑的比之前快了
然后我们会惊喜的发现,该是70分还是70分
嗯。。。

那么我们可以想一下能不能在累加和数组sum[]里面做点手脚
我们可以想一下,假设a区间里的数能被7整除
那么在其他包含这个a区间的其他区间里不管有没有a区间它%7的结果都是不变的

那么我们的sum[]记录的是1到i的累加和,如果让它们等于%7的结果,那么当sum[i] == sum[j], 时i 到 j 中间的数的累加和是可以被7整除的

同时我们用贪心的思想,如果%7的话结果只有0 ~ 6,我们记录0 ~6最先出现的下标和最后出现的下标,也就是当%7 == 1到6每一种结果的最大情况,最后再比较这7种最大情况输出就行了。

代码

#include<bits/stdc++.h>

#define ll long long
#define MAXN 5000010

using namespace std;

int a[MAXN], sum[MAXN], l[MAXN], f[MAXN];
int ans = 0;
int n;

int main()
{
	scanf("%d", &n);
	sum[0] = 0;
	for(int i = 1; i <= n; ++i){
		scanf("%d", &a[i]);
		sum[i] = (sum[i - 1] + a[i]) % 7;
	}

	for(int i = 1; i <= n; ++i) l[sum[i]] = i;
	for(int i = n; i >= 1; i--) f[sum[i]] = i;
	for(int i = 0; i <= 6; ++i) ans = max(ans, l[i] - f[i]);
	printf("%d\n", ans);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BIGBIGPPT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值