hdu 2608 0 or 1

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2608 

题目大意是定义一个T(n)为n所有正因子之和。然后定义S(n)为T(1)+T(2)……T(n)之和,求S(n)对2取余。

显然这是一个数论题,数据范围是32位整数,范围很多大,可以猜测,应该存在某种规律。

一定要敢于尝试,而且不要手懒,我们可以很快的暴力打一个100范围的T(n)表,然后看看,能不能找出规律。这里一定不要着急,有时候直接打S(n)的表可能看不出结果,所以一定要慢慢来。

暴力打表代码如下:

#include 

#define M 100

int a[M];
int main()
{
    int i,j;
    for(i=1;i
看到结果,我们发现大部分数据都是0,只有少部分是1,分别是1、2、4、8、9、16、18、25、32、36……细心点会发现T[i*i]会是,T[2*i*i]也是1,当你看出这一点时,这题可做了。

题目给出N,只需求出[1,N]有多少个这样的数记为Cnt,然后把Cnt%2就可以了。像这样:

for(Cnt=0,i=1;i
这需要考虑如果2*i*i能写成a*a,这样就多计数了一次,但是显然可以证明,不存在那样的数。

如果在舍得动一下脑筋就可以写成:

#include 
#include 

int main()
{
    int T,s,N,k;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&N);
        k=sqrt(N);
        s=k;
        while(k*k*2>N)
        {
            k--;
        }
        s+=k;
        printf("%d\n",s&1);
    }
    return 0;
}
如果再肯多想一点,sqrt(N/2.0)就是2*i*i的上限所以就可以这样写:
#include 
#include 

int main()
{
    int T,N;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&N);
        printf("%d\n",((int)sqrt(N)+(int)sqrt(N/2.0))&1);
    }
    return 0;
}

其实sqrt(N/2)也是对的。显然偶数肯定对,其实奇数时也对的,因为可以证明sqrt(a)与sqrt(a+0.5)在取整之后一定一样,sqrt(a)可能为整数,但sqrt(a+0.5)是不可能为整数的,所以里面加上0.5也是不能使整数部分加一的。但是懒得想这么多,保险起见,还是尽量别丢精度。

你可能感兴趣的:(数论,HDOJ,解题报告)