Little Difference(UPC-5118)

题目:

小利迪亚喜欢玩数字。今天她有一个正整数n,她想分解它是正整数的产物。
由于Lidia很少,她喜欢玩数字没有什么区别。所以,所有的数字
分解应该最多相差一个。当然,在所有数字的产品
分解必须等于n。她认为两个分解相同,当且仅当它们相同
具有相同数量的整数,并且有一个将第一个转换为第二个的置换
一。
写一个程序,找到所有的分解,这是Lidia今天可以玩的。
Input:
输入的唯一一行包含一个整数n(1≤n≤1e18)。
Output:
在第一行输出n的分解数,如果这个数是无限的,则输出-1。如果号码的分解是有限的,每行打印一个。在每一行中首先打印数字ki
元素分解。然后打印ki整数在任何顺序分解。别忘了

仅仅按元素顺序不同的分解被认为是相同的。

Examples 
input: 
12 
output: 

1     12 
3     2     3 
2     2     3     3

input: 

output: 

-1

这个题目原来是这样的,

后来这题改了,只要输出个数即可。就是上述示例Output第一行。

但是我们做题时:因为改了题目,题目读出来很多意思

因为当时的题目有几行一直干扰着我们队。

只到杨哥哥他们队做出来后,回去告诉我们才知道正确的题意是什么。


题意:

主人公小L,她喜欢数字N,想把它分解,且分出来的数字一定要是相差值<=1的.

比如        12=3×4,    12=2×2×3;    12=12;

为什么12=12呢,其实这是考虑到质数的情况,你看质数没有因子,只有1和它本身,

要是你说它本身都不算吗?那一个数总有它的分解方法吧!

(以上都是瞎扯     和    题目扯在一起)。管他呢反正就是最后就是+1;


题解:

第一种情况:

    题目提到了如果有无限个分解方法就要输出-1.

    1的确是一种情况,1=1,1=1×1,1=1×1×1................

    4也是:

    4=2×2,4=2×2×1,4=2×2×1×1,    4=2×2×1×1×1.........

所以2的次方都满足题意,且的确是无限个分法。

第二种情况:

(拿36为例子)

    分三部分:A、B、C    ans=A+B+C

A    36=2×2×3×3,    36=3×3×4;

B    36=6×6

C    36=36

A、部分就是:

正儿八经地符合题意,只要枚举两个数    i  ,  i+1

把tmp=n, 将    i  ,(i+1)(前提是能整除)来除tmp,只要当tmp==1就满足A的情况。

B、就是判断:

可能是两个数一模一样或者相差1吧,两个数的乘积==N

这时需要判断        t=sqrt(n);

n==t*t        n==t*(t-1)        n==t*(t+1);

只要满足一个就可以ans++;

C、一开始就提到可能是本身无需分解。ans++;

理论现行——算复杂度:对于B,C两部分就是O(1),对于A部分对于1e18的数据有点牵强,但是认真想一想要是满足第一种情况肯定是    3个或者以上的    i 或者    i+1相乘。

所以这个复杂度应该是    根号三的N    对于1e18->1e6的复杂度。游刃有余。

最后贴上代码,要是https://blog.csdn.net/axuhongbo/article/details/78570773

还有杨哥哥的“热心讲解”。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
     ll n;
     scanf("%lld",&n);
     ll ans=0,tmp=n;
     while(tmp%2==0){
        tmp>>=1;
     }if(tmp==1){
        return 0*printf("-1\n");
     }
     for(ll i=2;i*i*i<=n;i++){
          if(n%i==0){
            tmp=n;
            while(tmp%i==0){
                tmp/=(i);
            }
            while(tmp%(i+1)==0){
                tmp/=(i+1);
            }
            if(tmp==1){
                ans++;
            }
          }
     }
     ll t=sqrt(n);
     if(t*t==n){
        ans++;
     }else if((t+1)*t==n){
        ans++;
     }else if((t-1)*t==n){
        ans++;
     }
     printf("%lld\n",ans+1);
     return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值