SGU105 Div 3
题目大意:
描述
有一个这样的数列:1, 12, 123, 1234, ..., 12345678910, ... 。计算这个数列的前N项中,能被3整除的数的个数。
输入
整数N (1<=N<=2^31 - 1)。
输出
一个整数,答案.
样例输入
4
样例输出
2
巨水题一道。。。
首先,能被3整除的数,其各位数字和也能被3整除(小学数学)
那么我们只需要考虑每次加进来的数字i(即由1~i组成的大数字)
显然,当i为1时,答案为0,此时这个数字mod 3==1
i为2时,答案为1,此时这个数字mod 3==0
i为3时,答案为2,此时这个数字mod 3==0
i为4时,答案为2,此时这个数字mod 3==1
...
对于任意一个由(1~N)所组成的数字,我们可以将它每三个数每三个数分开
我们会发现,对于任意一组(i1=3*k+1,i2=3*k+2,i3=3*k+3),都有
(i1+i2+i3) mod 3==0
所以我们只需要考虑最后没有分组的数字
剩下一个数字j1=3*m+1时,这个数字(1~j1)mod 3==1
剩下两个数字j1=3*m+1,j2=3*m+2时,这个数字(1~j2)mod 3==0
剩下三个数字又会被分为一组,所以这个数字mod 3==0
综上所述,对于由(1~N)组成的数字,当N mod 3!=1时,这个数字mod 3==0
问题转化成了,从(1~N)中找有多少个数字i满足i mod 3!=1
答案已经很显然了:(N*2)/3 (或(N/3)*2+(N%2==0))
值得注意的一点,因为N比较大,N*2有可能会炸longint,所以使用前者的OIer注意一下long long的问题
下面附上我的代码(其实很简单):
#include <stdio.h>
#include <stdlib.h>
int n;
void init()
{
scanf("%d",&n);
printf("%d",(n/3)*2+(n%3==2));
return ;
}
int main()
{
init();
return 0;
}