题目描述:
给你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.
思路:暴力模拟肯定不行,试着用前缀和去做但发现无论怎么剪枝都会tle,之后看到题解后发现可以把每个前缀和都mod7,之后0到6循环一遍找到两个相同的mod前缀相减就行
,但hack数据过不了
先附上被hack的代码
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
long long meme[50009];
long long max_=0;
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int sum,i,i2,i3;
cin>>sum;
for(i=0;i<sum;i++)
cin>>meme[i];
for(i=1;i<sum;i++)
meme[i]+=meme[i-1];
for(i=0;i<sum;i++)
meme[i]%=7;
for(i=0;i<7;i++)
{
for(i2=0;i2<sum;i2++)
{
if(meme[i2]==i)
break;
}
for(i3=sum-1;i3>i2;i3--)
{
if(meme[i3]==i)
break;
}
if(i3>i2)
if(i3-i2>max_)
max_=i3-i2;
}
cout<<max_<<endl;
return 0;
}
之后发现由于如果两个前缀和相减,之间的区域和等于被查找的前缀数a之后的那一个加上被查找的后缀数b之间的和,换句话说查找范围为(a,b],这样就无法查找由第一个数作为前缀数的区间,正确的做法是数组输入从i=1开始,留一个a[0]=0
ac代码
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
long long meme[50009];
long long max_=0;
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
int sum,i,i2,i3,it,iu;
cin>>sum;
for(i=1;i<=sum;i++)
cin>>meme[i];
for(i=2;i<=sum;i++)
meme[i]+=meme[i-1];
for(i=1;i<=sum;i++)
meme[i]%=7;
for(i=0;i<7;i++)
{
for(i2=0;i2<=sum;i2++)
{
if(meme[i2]==i)
break;
}
for(i3=sum;i3>i2;i3--)
{
if(meme[i3]==i)
break;
}
if(i3>i2)
if(i3-i2>max_)
max_=i3-i2;
}
cout<<max_<<endl;
return 0;
}