杭电1215解题方法总结

        七夕节那天,月老来到数字王国,他在城门上贴了一张告示,并且和数字王国的人们说:"你们想知道你们的另一半是谁吗?那就按照告示上的方法去找吧!"
人们纷纷来到告示前,都想知道谁才是自己的另一半.告示如下:

        值此七夕佳节来临之际,为感谢广大群众对我月老的热爱,特将大家的另一半的寻找方法公布如下:将你的编号(数字王国的每个人都有唯一的编号)所有因子加起来得到一个编号,这个编号的主人就是你的另一半。

        祝大家找到自己的另一半。

                                                    ———月老


数字N的因子就是所有比N小又能被N整除的所有正整数,12的因子有1,2,3,4,6.
你想知道你的另一半吗?

 

Input

输入数据的第一行是一个数字T(1<=T<=500000),它表明测试数据的组数.然后是T组测试数据,每组测试数据只有一个数字N(1<=N<=500000).

 

Output

对于每组测试数据,请输出一个代表输入数据N的另一半的编号.

 

Sample Input

3

2

10

20

 

Sample Output

1

8

22

 


枚举方法

枚举到根号

 

time 468MS  memory 1052K  len 460 B

 

#include<stdio.h>

#include<math.h>

#define EOF 10e-6

int main()

{

    int k,i,c;

    scanf("%d ",&k);

    for(i=0;i<k;i++)

    {

        int a,j,sum=0;

        scanf("%d",&a);

        c=sqrt(a)+EOF;   //精度截断问题

        for(j=2;j<=c;j++)

        {

            if(a%j==0)

            {

                if(j!=a/j) sum=sum+j+a/j;  // eg:4=2*3

                else sum=sum+j;  //eg:4=2*2;

            }

        }

        sum++;   //加上因子1

        printf("%d\n",sum);

    }

    return 0;

}

 

 

预处理

 

1

类似于筛法

比如2,3,4,5,6,7,8,9,10,11,12

i=2时,所有2的倍数的数字都有因子2

   令a[4]=a[4](0)+i(2); a[6]=a[6](0)+i(2); 

      a[8]=a[8](0)+i(2) ...... a[12]=a[112](0)+i(2)

i=3时,所有3的倍数的数字都有因子3

  此时a[6]=a[6](2)+i(3);.....a[12]=a[12]+i(3)

  a[12]此后会依次加上i=4i=6

最后输出结果在加上因子1

 

time 78MS  memory 3012K  len 334 B

 

#include<stdio.h>

int a[500001];

int main()

{

    int i,j,k,n;

    for(i=2;i<=250000;i++)

    {

        for(j=i+i;j<=500000;j=j+i)

            a[j]=a[j]+i;

    }

    scanf("%d",&k);

    while(k--)

    {

        scanf("%d",&n);

        if(n==1) printf("0\n");

        else printf("%d\n",a[n]+1);

    }

    return 0;

}

  

2

也可以先加上因子1;再处理

两种写法意思一样;

但速度会变慢

 

time 124MS  memory 3012K  len 319 B

 

#include<stdio.h>

int a[500001];

int main()

{

    int i,j,k,n;

    for(i=0;i<500001;i++) a[i]=1;

    for(i=2;i<500001;i++)

    {

        for(j=2;j*i<500001;j++)

        a[j*i]+=i;

    }

    scanf("%d",&k);

    while(k--)

    {

        scanf("%d",&n);

        printf("%d\n",a[n]);

    }

    return 0;

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值