UESTC 1901 方方是个坏孩子

方方是个坏孩子

Time Limit: 1000 ms Memory Limit: 65535 kB 

 

 

Description

方方是一个调皮的孩子,每天到处搞破坏把妹子,邻居都讨厌他。一天方方不小心把邻居老姚神的魔法棒给摔成了n段,长度分别为a0,a1,……,an-1。方方虽然调皮,但还是不敢招惹可怕的老姚神,修复魔棒是如此的艰难,只能请求另一个邻居哈利波特大用魔法把魔棒修复,但哈利波特大正在忙着统计霍格沃茨的男女比例,没有太多时间帮方方修魔棒,只答应只为方方使用一次魔法。


哈利波特大的魔法很奇怪,魔法只能把一段连续的魔棒片段连在一起,并且连接的片段的长度之和必须为p的倍数,(例如n=6,p=11,a0到an-1分别为11,11,1,6,7,9,哈利波特大可以把a0和a1连在一起,或者把a3, a4, a5连在一起),注意老姚神的魔棒必须按顺序接,也就是说,方方不能随意改动a0, a1,... an-1的顺序。


方方想把尽可能多的魔法棒片段连在一起,现在想找你帮忙。

Input

第一行包含一个正数 T (T <= 50),表示数据组数。
接下来每组数据包含两行。
第一行包含两个整数 n, p (1<=n<=100000, 1<=p<=11),代表魔法棒有n段,连接的长度之和必须为p的倍数。
第二行包含n个正整数分别表示a0,a1……,a(n-1),(1 <= ai <= 1000, 0 <= i < n)。

Output

对于每组数据输出一行,表示能最多能连接起来的魔棒片段个数。.

Sample Input

5
6 11
11 11 1 6 7 9
1 2
1
1 3
3
10 2
1 2 3 4 5 6 7 8 9 10
4 3
1 2 3 4

Sample Output

3
1
1
9
3

Hint

注意在第二组样例中,事实上魔法根本无法施展,但是答案是1,因为即使不使用魔法,片段也是一个一个的~

 

 

#include<stdio.h>  
#include<math.h>  
#include<string.h>  
#include<stdlib.h>  
#define N 100005  
const int P=15;  
int a[N],sum;    //定义 sum(第i个sum)= (a[1] + a[2] +... + a[i]) 称为i位置的前缀和。 (1 <= i <= n),特别的有sum[0] = 0。 
int front[P];     //front[i]代表最小的下标x,使得sum[x] % P = i,rear[i]则代表最大的下标x满足相同的条件。枚举答案即可; 
int rear[P];     
int Max(int a,int b)      
{  
    return a>b?a:b;  
}  
int main()  
{  
    int T,i,n,p;  
    scanf("%d",&T);  
    while(T--)  
    {  
        scanf("%d%d",&n,&p);   
        sum=0;  
        for(i=0;i<p;i++)  
        {  
            front[i]=-1;  
            rear[i]=-1;  
        }  
        for(i=0;i<n;i++)  
        {  
            scanf("%d",&a[i]);  
            sum+=a[i];  
            sum%=p;        //sum代表前i个数的和对P取模的余数  
  
            if(front[sum]==-1)  
                front[sum]=i;         //记录最先出现的满足条件下标i  
  
            rear[sum]=i;             //记录最后出现的满足条件下标i  
        }  
        int ans=1;  
        for(i=0;i<p;i++)  
            if(front[i]!=-1&&rear[i]!=-1)  
            {  
                if(i==0)  
                    ans=rear[i]+1;      //余数为零下标加一就是答案!!  
                else  
                    ans=Max(ans,rear[i]-front[i]);  
            }  
        printf("%d\n",ans);  
    }  
    return 0;  
} 
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值