毫秒级解题方法:
新思路:
利用隔板法,假设有一排小球共2021个,代表数字2021,如果在其中插入1个板子,小球就被分成了两组,一组x个,另一组y个,且x + y必然为2021,一共有C12020种情况(2021个数有2020个插板子的位置),所以把2021分成5个数,就相当于把球分成5组,只需要插入4个板子即可,一共C42020种方案。(该方法来自y总)
#include <stdio.h>
typedef long long LL;
int main()
{
LL sum=1;
int i,N,n;
scanf("%d",&N);
n = N - 1;
for(int i = 0; i < 4; i++)//N - 1个位置选 4个
{
sum *= n - i;
sum /= i + 1;
}
printf("%lld",sum);
return 0;
}
答案:691677274345 【运行时间:1ms】
秒级解题方法
之前的思路:
1、如果用五个for循环嵌套枚举所有可能性大约需要计算20005(数量级1015)次,普通电脑一天肯定跑不完(计算机大概计算107~109/s) ,所以需要简化减少for循环嵌套。
2、一个正整数N (N>2) 分解为两个正整数的和,分解过程中确定其中一个数,另一个数就确定了,一共有N-1种可能性;
3、正整数 N 分解为五个正整数可以先分解为两个数,然后再选其中一个分解,重复四次即可分解得五个数。
4、在 C 分解为 d 和 e 时,利用上述第二条 可知一共有C-1种可能性。所以可以简化为三个for循环解答。
代码如下:
#include<stdio.h>
typedef long long LL;
int main()
{
int a,b,c,N;
LL sum=0;
scanf("%d",&N);
for(a = 1;a <= N-4;a++) //a最大时,N被分解为四个1和a,故a不大于N-4,以下同理
for(b = 1;b <= N - a - 3;b++)
for(c = 1;c <= N - a - b - 2;c++)
sum += (N - a - b - c - 1);
printf("%lld\n",sum);
return 0;
}
#答案为:691677274345 【运行时间:3~4s】