糖果

糖果

CallMeCad某天买了非常多的糖果并把它们分成N份,依次分别有1,2,3…,N个糖果。他想拿出其中的3份分给他的室友, 为了不让室友们闹意见,必须让这三份的糖果总数恰好能被三人均分。请问他一共有多少种不同的组合方案数?
输入
有多组输入数据,每组输入非负整数N(3≤N≤106)。
输出
每组数据输出一个整数独占一行,表示共有多少种方案,由于可能会很大,最后结果对10^9+7取模。
样例输入
3
4
5
样例输出
1
2
4

一.题目分析

  1. 先将n分成三类:3的倍数, 3的倍数余1, 3的倍数余2
  2. 再考虑取出的三份糖果的来源可能有哪几种情况
  3. 将n个糖果分成3类:x={3的倍数}, y={3的倍数余1}, z={3的倍数余2}
  4. 一共有4种情况:
    1. 取于x,x,x
    2. 取于y,y,y
    3. 取于z,z,z
    4. 取于x,y,z
  5. 然后分别对这几种情况进行计算
  6. 最后不要忘记取模

二.AC代码

#include<stdio.h>
#include<math.h>
long long int f(long long int x);
int main()
{
    long long  int n,ans,mod=1000000007;
    while(~scanf("%lld",&n))
    {
        if(n%3==0) 
		{
			ans=(n*n*n)/27;//注意此处不能用(long long )pow(n/3,3),否则就会一直wrong answer,用后面那个999999这个数据不一样
			ans=(ans+3*f(n/3));
		}
        else if(n%3==1) 
		{
			ans=((n-1)/3)*((n-1)/3)*(((n-1)/3)+1);
			ans=(ans+2*f((n-1)/3)+f(((n-1)/3)+1));
		}
        else if(n%3==2) 
		{
			ans=((n-2)/3)*(((n-2)/3)+1)*(((n-2)/3)+1);
			ans=(ans+2*f(((n-2)/3)+1)+f((n-2)/3));
		}
        printf("%lld\n",ans%mod);
    }
    return 0;
}
long long int f(long long int x)
{
	if(x<3) return 0;
	long long int y=1;
	for(long long int i=x;i>x-3;i--)
	{
		y=(y*i);
	}
	y/=6;
	return y;
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值