zoukankan      html  css  js  c++  java
  • 能量球

    能量球 (enb.pas/c/cpp)
    题目描述
    sideman 有着一个你们所不知道的秘密。实际上, sideman不是地球人,而是遥远的Gliese 行星的生物。sideman 虽然身在地球,但是时刻盼望着能够回到Gliese 去。终于有一天, sideman得到了几颗蕴含着无数能量的能量球。经过漫长艰苦的研究, sideman 搞清楚了这些能量球的规律。首先,能量球上面有一个正整数N,运用激发手段可以使得能量球上的正整数变为原来的数的一个真因子( A 是B 的一个真因子,等价于B 是A 的整数倍且0<A<B),并且放出单位数量的能量。当然,变为哪一个真因子是可以自由选择的。现在sideman 想知道每颗能量球最多可以放出多少能量,以及有多少种方式达到这个目的(两种操作方式被认为是不同的,当且仅当它们的操作序列中存在不同的真因子)。

    分析:

       首先,我们对一个数进行质因数分解,能量数就是它的质因数,所以对一个是进行质因数分解,但是数据的范围为10^9,但我们可以循环到sqrt(n),这样我们可以求出n的质因数,(但一个数是质因数时,我们可以看当n mod 它1 到n的质因数后,若这个数还是>1,那么它是质因数,他的质因数个数+1);那么它的方案数呢?若我们知道他的所有质因数后,将这些质因数拼成因数,所以方案数就是组合数,ans=n!/(a1!*a2!.....),先分组后分配。(可以先处理出阶乘,也可以一起算,一边乘一边除)。

      注意,当n=0时,能量为0,但这也算一种方案,所以方案是为1。

    代码实现:

    program exam;

    const

      p=1000000000;

    var

      i,j:longint;

      ans,i1,total,t,k:int64;

      a,a1:array[1..400000] of int64;

      c:array[1..400000] of int64;

      jj:array[0..30] of int64;

      b:array[1..4000000] of boolean;

    begin

      assign(input,'enb.in');

      reset(input);

      assign(output,'enb.out');

      rewrite(output);

      t:=0;

      while not eof do

      begin

        inc(t);

        readln(a[t]);

      end;

      for i:=1 to 20 do

      begin

        jj[i]:=1;

        for j:=1 to i do

          jj[i]:=jj[i]*j;

      end;

      fillchar(b,sizeof(b),true);

      for i:=2 to trunc(sqrt(p)) do

        if b[i]=true then

        begin

          k:=trunc(sqrt(p)) div i;

          for j:=2 to k do

          begin

            i1:=i*j;

            b[i1]:=false;

          end;

        end;

      for i:=1 to t do

      begin

        total:=0;

        ans:=1;

        a1:=a;

        fillchar(c,sizeof(c),0);

        for j:=2 to trunc(sqrt(a[i])) do

          if (a1[i] mod j=0) and (b[j]=true) then

            repeat

              inc(total);

              inc(c[j]);

              a1[i]:=a1[i] div j;

            until a1[i] mod j<>0;

        if a1[i]>1 then

          inc(total);

        ans:=jj[total];

        for j:=1 to trunc(sqrt(a[i])) do

          if c[j]>1 then

            ans:=ans div jj[c[j]];

        if total=0 then

          writeln(0,' ',1)

        else

          writeln(total,' ',ans);

      end;

      close(input);

      close(output);;

    end.

  • 相关阅读:
    android 68 单元测试
    android 67 生成和解析xml
    android 66 sharedperference的使用
    android 65 文件访问权限
    android 64 sd卡读写的操作
    EditText操作收集
    android Fragments详解六:处理fragement的生命周期
    Context
    android 63 Fragment
    在Centos安装oracle_11gR2进度68%"Error in invoking target mkldflags ntcontab.o nnfgt.o of makefile..”
  • 原文地址:https://www.cnblogs.com/fengxiudong/p/6017220.html
Copyright © 2011-2022 走看看