P3131 [USACO16JAN]Subsequences Summing to Sevens S

题目描述
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 NN (1 \leq N \leq 50,0001≤N≤50,000). The next NN

lines each contain the NN integer IDs of the cows (all are in the range

0 \ldots 1,000,0000…1,000,000).

输出格式
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

用到一个定理:若两个数相减%7==0,那么这两个数%7的余数一定相同!!
这样的话瞬间就简单了 我们只要求出相同的一个余数第一次和最后一次之间的长度即是最长长度! 但是我们不知道哪个余数最长,所以: 枚举0~6 共7个余数各自的最长长度,再在他们7个里找最长的!

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
#include <climits>
#include <map>
#include <cmath>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
ll n,a;
ll s[maxn],f[maxn],se[maxn];
inline ll read()
{
    ll f = 1, x = 0;
    char ch;
    ch = getchar();
    while (!isdigit(ch))
    {
        f = -1;
        ch = getchar();
    }
    while (isdigit(ch))
    {
        x = x * 10 + ch - 48;
        ch = getchar();
    }
    return x * f;
}
void write(ll x)        
{        
    if(x < 0) {        
        putchar('-');        
        x = -x;        
    }        
    if(x > 9)        
        write(x/10);        
    putchar(x % 10 + '0');        
    return;        
}        
int main()
{
   std::ios::sync_with_stdio(false);
   cin.tie(0);
   cout.tie(0);
   n=read();
   for(ll i=1;i<=n;i++){
     a=read();
     s[i]=(s[i-1]+a)%7;
   }
  ll ans=0;
   for(ll i=n;i>=1;i--){
     f[s[i]]=i;
   }
   for(ll i=1;i<=n;i++){
     se[s[i]]=i;
   }
   for(ll i=0;i<=6;i++){
     ans=max(ans,se[i]-f[i]);
   }
   write(ans);
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值