寒假作业1 e题
第七集,奇思妙想
TimeLimit:2000MS MemoryLimit:128MB
64-bit integer IO format:%I64d
Problem Description
在经过一个比赛的小插曲后,小A不仅得到主办方的赏识后,还捞到了一大笔钱。有了足够的钱后,他继续出发前往那个聚会城市。由于小A和小C每天都需要赶路,他们需要多买一些舒适的袜子。在离开这个城市前,他先逛了一家袜子批发商店,该商店将不同数量的袜子放入一个个盒子中,且将盒子排成一排,小A看到这样的情景,顿时好奇(程序员的本能):
若把这些箱子围成一个圈,并且拿走一段连续的箱子,且箱子中的袜子的总数量正好等于小A要买的袜子的数量M,有多少种拿法?(假设有N个盒子,盒子编号1-N)、
同在小A和小C买完了袜子之后,继续朝着聚会城市出发…
Input
有多组测试案例,
每组测试案例,第一行输入一个正整数N,M(1<=N<=10^6, 1<=M<=10^8),表示有N个箱子。
第二行输入N个非负整数Ai(1<=Ai<=100)、分别表示连续箱子里面的袜子的数量、
Output
对于每组测试案例,输出有多少种方法、
SampleInput
2 3 1 3 0
SampleOutput
2 3 1 3 0
思路:
这题使用尺取法来做,先设置i,j=0指向数组头,sum代表连续一段数组的和,首先让sum等于a[0],开始循环,若sum大于等于m,若sum>=m,证明这把尺太长,需要减去前面,sum减去a[i],++i;
假如sum等于m,方法种数加一,若sum<m,证明这把尺不够长,需要加后面,++j,sum加上a[j],循环直到i等于n结束.因为这题箱子是一个圈,所以可以把数组复制到后面,a[i+n]=a[n];如果数组总和等于m,直接输出1,小于输出0;
int lw(int v[],int n,int m)
{
int i,j,k,sum;
i=j=k=0; sum=v[0];
while(i<n)
{
if(sum>=m)
{
if(sum==m)
k++;//方法种类加一//
sum-=v[i];
++i;
}
else
{
++j;
sum+=v[j];
}
}
return k;
}