Gym 101612L Little Difference

Problem L. Little Difference

Input file: little.in
Time limit: 3 seconds
Output file: little.out
Memory limit: 512 megabytes

Little Lidia likes playing with numbers. Today she has a positive integer n, and she wants to decompose
it to the product of positive integers.

Because Lidia is little, she likes to play with numbers with little difference. So, all numbers in
decomposition should differ by at most one. And of course, the product of all numbers in the
decomposition must be equal to n. She considers two decompositions the same if and only if they
have the same number of integers and there is a permutation that transforms the first one to the second
one.

Write a program that finds all decompositions, which little Lidia can play with today.

Input
The only line of the input contains a single integer n (1 ≤ n ≤ 1018).

Output
In first line output the number of decompositions of n, or −1 if this number is infinite. If number
of decompositions is finite, print all of them one per line. In each line first print number ki of
elements in decomposition. Then print ki integers in this decomposition in any order. Don’t forget that decompositions which are different only in order of elements are considered the same.

Examples
in:
12
out:
3
1 12
3 2 3
2 2 4 3

in:
1
out:
-1

In the second example 1 can be represented as product of any number of ones.

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

题意大概是这个意思:将一个数分解,分解出的每个因子之间差值都不超过1,如果因子有无限个(比如带1),打印-1,否则打印出所有可能,每种可能 打印出的各个数大小任意排列。
1e18的数据,直接枚举1e9的话会超时,我们可以开三次方,然后把两个数的情况进行特判。判重通过(按照顺序枚举+判定n%i==0)来完成。

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+7;
vector<ll>vec[maxn];
//特判2的倍数一定是-1
int  check(ll n)
{
    while(n>1)
    {
        if(n&1)return 1;
        n>>=1;
    }
    return 0;
}
int top ;
void solve(ll nn)
{

     vec[++top].push_back(nn);
     for(ll i=2;i*i*i<=nn;i++)
     {
         ll n =nn;
         vector<ll>o;
         if(n%i==0)//判重,例如27判定时会用到
         {
             while(n%i==0)
             {
                 n/=i;
                 o.push_back(i);

             }
             while(n%(i+1)==0)
             {
                  n/=(i+1);
                   o.push_back(i+1);

             }
             if(n==1)//否则不满足任意两个因子差值为1
                vec[++top] =o;
         }
     }
     //特判两个数的情况
     ll u = sqrt(nn);
     if(u*u==nn)
     {
         vec[++top].push_back(u);
         vec[top].push_back(u);
     }
     else if(u*(u+1)==nn)
     {
          vec[++top].push_back(u+1);
         vec[top].push_back(u);
     }
     else if((u+1)*(u+1)==nn)
     {
             vec[++top].push_back(u+1);
         vec[top].push_back(u+1);
     }
}
int main()
{
//    freopen("little.in","r",stdin);
//    freopen("little.out","w",stdout);
    long long n,m;
    long long i;
   scanf("%lld",&n);
   if(n==1||!check(n))
   {
       printf("-1\n");
   }
   else
   {
       top = 0;
        solve(n);
       printf("%d\n",top);

       for(int i=1;i<=top;i++)
       {
           printf("%d",(int)vec[i].size());

           for(int j=0;j<vec[i].size();j++)
           {

               printf(" %lld",vec[i][j]);
           }
           printf("\n");
       }
   }
    return 0;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值