Little Difference Gym - 101612L 思维

题意:

给你一个数n,你需要输出它可以由那几个数相乘构成,我们设可以由x个数构成,这x个数中最小值为minn,最大值为maxx,那么要求maxx-minn<=1

问你满足上面要求的情况有多少种。如果一个数的构成方式由无数种就输出-1

样例解释:

输入:

12

输出:

3

1 12

3 2 3 2

4 3

12有三种满足题意的构成方式,分别是12、2*3*2、4*3

 

输入

1

输出

-1

因为1的构成可以是1、1*1、1*1*1、1*1*1*1无数种

 

题解:

你会发现输出-1的情况都是2的次幂,例如1、2、4、8、16.特判一下就可以了

其他情况首先n本身算一次。后面就是两个数相乘得到n,这种情况设定x=sqrt(n)

判断一下x*x==n、x*(x-1)==n、x*(x+1)==n

之后就是多个数相乘(大于两个),n最大是1e18,那么我们枚举1到n1/3的所有数,判断就可以

 

代码:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn = 1e4 + 5;
const int mod = 1000000007;
vector<ll>r[maxn],que;
int main()
{
    ll n;
    freopen("little.in","r",stdin);
    freopen("little.out","w",stdout);
    scanf("%lld",&n);
    if((n&(-n))==n)
    {
        printf("-1\n");
        return 0;
    }
    ll pos=0;
    //que.push_back(1);
    que.push_back(n);
    r[pos]=que;
    pos++;
    que.clear();
    for(ll i=2;i*i*i<=n;++i)
    {
        ll tmp=n;
        if(tmp%i==0)
        {
            while(tmp%i==0)
                que.push_back(i),tmp/=i;
            while(tmp%(i+1)==0)
                que.push_back(i+1),tmp/=(i+1);

            if(tmp==1)
            {
                r[pos]=que;
                pos++;
            }
            que.clear();
        }
    }
    ll tmp=sqrt(n);
    if(tmp*tmp==n)
    {
        que.push_back(tmp);
        que.push_back(tmp);
        r[pos]=que;
        pos++;
        que.clear();
    }
    if(tmp*(tmp+1)==n)
    {
        que.push_back(tmp);
        que.push_back(tmp+1);
        r[pos]=que;
        pos++;
        que.clear();
    }
    if(tmp*(tmp-1)==n)
    {
        que.push_back(tmp);
        que.push_back(tmp-1);
        r[pos]=que;
        pos++;
        que.clear();
    }
    printf("%lld\n",pos);
    for(ll i=0;i<pos;++i)
    {
        ll len=r[i].size();
        printf("%lld ",len);
        for(ll j=0;j<len-1;++j)
        {
            printf("%lld ",r[i][j]);
        }
        printf("%lld\n",r[i][len-1]);
    }
    return 0;
}

 

posted @ 2020-11-14 17:01  kongbursi  阅读(67)  评论(0编辑  收藏  举报