Candy


思路:一开始发现了规律对这些数分别%3,一共有四种情况,(1)0+0+0(2)0+1+2(3)1+1+1(4)2+2+2;代码借鉴了埃筛逻辑,设立一个数组a【i】,那么a【i】=a【i-1】+i和其他数组成的可行组合,那么就只用遍历1e6次(可能还是有点长),所以时间超限了,但这里还是记录一下(注意这个是错误代码)
#include<stdio.h>
#define ll long long
#define K 100007
int a[K]={0};
void is_a(){a[3]=1;a[4]=2;a[5]=4;for(int i=6;i<K;i++){int t=i%3;if(t==0){a[i]=a[i-1]+(i/3)*(i/3);}if(t==1){a[i]=a[i-1]+(int)(i/3)*(int)(i/3);}if(t==2){a[i]=a[i-1]+(int)(i/3+1)*(int)(i/3);}}
}
int main(){int N;is_a();while(scanf("%d",&N)!=EOF&&N!=0){printf("%d\n",a[N]%1000000007);}
}
然后是看完大佬的代码后。发现可以不用循环,直接计算得出,那就大大缩短了时间。首先已知N,可以知道num(0)=N/3;num(1)=(N+2)/3;num(2)=(N-1)/3;num(0)表示N前面模3等于0的数的个数,所以就只要用排列组合就可以计算,比如第一种情况,可以是C(num(0),3)=num(0)*(num(0)-1)*(num(0)-2)/3*2*1;
AC代码
#include<stdio.h>
#define ll long long
#define MOD 1000000007
int main(){ll N;while(scanf("%lld",&N)!=EOF&&N!=0){ll n0,n1,n2;n0=N/3;n1=(N+2)/3;n2=(N+1)/3;ll ans=0;//0 0 0if(n0>=3){ans=(ans+n0*(n0-1)*(n0-2)/6)%MOD;}//1 1 1if(n1>=3){ans=(ans+n1*(n1-1)*(n1-2)/6)%MOD;}//2 2 2if(n2>=3){ans=(ans+n2*(n2-1)*(n2-2)/6)%MOD;}//1 2 0ans=(ans+n0*n1*n2)%MOD;printf("%lld\n",ans);}
}
