zoukankan      html  css  js  c++  java
  • LightOJ

    题意

    有一块矩形(也可能是正方形)的飞毯。

    给定飞毯的面积(n)和最小可能的边长(a),求可能有多少种不同边长的飞毯。((1<=a<=n<=1e12)

    如面积(n=6)时,({2,3})({3,2})算一种。

    题解

    本来想(sqrt(n))的复杂度直接枚举(n)的所有因数,发现(TLE)了。

    正解是把(n)质因数分解成(n=a_1^{b_1}a_2^{b_2}...a_n^{b_n}),然后(n)的因子的个数就是((1+b_1)*(1+b_2)...(1+b_n))

    我自做聪明的把上面得出的结果加上(1)(考虑到因子有(1)的情况),结果WA了一晚上。

    得出(n)的因子个数之后,再暴力枚举小于(b)的数,如果是(n)的因数就减掉。

    代码

    #include <bits/stdc++.h>
    
    #define FOPI freopen("in.txt", "r", stdin)
    #define FOPO freopen("out.txt", "w", stdout)
    #define FOR(i,x,y) for (int i = x; i <= y; i++)
    #define ROF(i,x,y) for (int i = x; i >= y; i--)
    
    using namespace std;
    typedef long long LL;
    const int N = 1e6 + 10;
    
    int Prime[N+100];
    
    void getPrime(int N)
    {
        memset(Prime, 0, sizeof(Prime));
        FOR(i, 2, N)
        {
            if (!Prime[i]) Prime[++Prime[0]] = i;
            for (int j = 1; j <= Prime[0] && Prime[j] <= N/i; j++)
            {
                Prime[Prime[j]*i] = 1;
                if (i % Prime[j] == 0) break;
            }
        }
    }
    
    int factor[N+100][2];
    
    int facCnt;
    LL Factor(LL x)
    {
        facCnt = 0;
        LL tmp = x;
        for (int i = 1; Prime[i] <= tmp/Prime[i]; i++)
        {
            factor[facCnt][1] = 0;
            if (tmp % Prime[i] == 0)
            {
                factor[facCnt][0] = Prime[i];
                while(tmp % Prime[i] == 0)
                {
                    factor[facCnt][1]++;
                    tmp /= Prime[i];
                }
                facCnt++;
            }
        }
    
        if (tmp != 1)
        {
            factor[facCnt][0] = tmp;
            factor[facCnt++][1] = 1;
        }
    
        LL res = 1;
        FOR(i, 0, facCnt-1)
            res *= (1+factor[i][1]);
    
        return res;
    }
    
    LL n, b;
    int t;
    
    int main()
    {
        getPrime(N);
    
        scanf("%d", &t);
        FOR(ca, 1, t)
        {
            scanf("%lld %lld", &n, &b);
            if (n < b*b)
            {
                printf("Case %d: 0
    ", ca);
                continue;
            }
    
            LL Sum1 = Factor(n) / 2;
            FOR(i, 1, b-1)
                if (n % i == 0) Sum1--;
            printf("Case %d: %lld
    ", ca, Sum1);
        }
    }
    
  • 相关阅读:
    oracle 分布式数据库
    oracle 触发器
    oracle 存储过程,函数和包
    oracle 回收站
    oracle PL/SQL程序设计
    oracle 使用 ALTER 操作列
    oracle 集合运算符
    软工实践作业(六)
    软工实践作业(五)
    软工实践作业(四)
  • 原文地址:https://www.cnblogs.com/ruthank/p/10910535.html
Copyright © 2011-2022 走看看