我的:
裸的尺取法,因为是m的倍数,所以先对每个数进行mod(m)运算,根据的是同余摩定理,之后直接判断一段连续的子序列和是不是m,就可以得出答案le;
题解是这样说的,感觉也挺有道理的:
前缀和是该点前面所有的数的和,然后取一下m的摩,当他们的有摩相等的时候,就说明存在子序列可以组成m的倍数,然后当n>=m,利用抽屉原理,肯定有重复的前缀和摩m的情况,所以存在。
我的:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<map>
#include<set>
#include<vector>
#include<string>
#include<cmath>
using namespace std;
const int maxn=100000+10;
#define PI acos(-1.0)
#define mod 1e9+7
bool cmp(const int a,const int b)
{
return a>b;
}
int main()
{
int Tcase;
scanf("%d",&Tcase);
for(int ii=1;ii<=Tcase;ii++)
{
int n,m;
scanf("%d%d",&n,&m);
int a[maxn];
int sum=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
a[i]=a[i]%m;
sum+=a[i];
}
if(sum<m)
{
cout<<"NO"<<endl;
continue;
}
if(sum%m==0)
{
cout<<"YES"<<endl;
continue;
}
int flag=1;
int l=0,r=0;
sum=0;
while(l<=r&&r<n)
{
while(sum<m&&r<n)//刚开始的时候没有加上这个r<n和后面的判断sum<m的情况,所以一直错,估计是因为死循环导致WA吧。
{
sum+=a[r];
r++;
}
if(sum<m)
break;
if(sum==m)
{
// cout<<l<<" "<<r-1<<endl;
cout<<"YES"<<endl;
flag=0;
break;
}
sum-=a[l];
l++;
}
if(flag)
cout<<"NO"<<endl;
}
return 0;
}