Codeforces Round #560 (Div. 3) D. Almost All Divisors

题目链接:http://codeforces.com/contest/1165/problem/D

题意:现在有n个数,他们都是某一个数的全部因子(不包含这个数本身和1),问能否找到这个数。如果不能输入-1。

解题心得:

  • 首先如果这些数是某个数的全部因子,那么排序之后首尾相乘就是这个数,并且排序之后按照对称的方式乘起来应该是相同的。例如 16 16 16的因子有 2 2 2 4 4 4 8 8 8。这三个数是关于 4 4 4对称的, 2 ∗ 8 = 4 ∗ 4 2*8=4*4 28=44
  • 还需要验证的一点是找到的这个数是否全部因子都在这 n n n个数中,如果直接对找到的这个数分解因子复杂度是 1 e 6 1e6 1e6并且 t t t组数据会 T L E TLE TLE,这个时候就需要换一个思路,首先要明白的是一个数的因子的因子仍然是这个数的因子,这样就可以对三百个数进行分解,查看分解出来的因子是否全部包含在这 n n n个数之中,这样复杂度就是 300 ∗ 1000 300*1000 3001000,即使是 t t t组数据也能过。


#include <bits/stdc++.h>
using namespace std;
typedef complex<double> cp;
typedef long long ll;
const int maxn = 2e5+100;
const double pi = acos(-1);

int t, n;
ll num[maxn];
bool vis[maxn*5];//vis记录n个出现过的数

void init() {
    scanf("%d", &n);
    for(int i=1;i<=n;i++) {
        scanf("%lld", &num[i]);
        vis[num[i]] = true;
    }
    sort(num+1, num+1+n);
}

int main() {
    //    freopen("1.in.txt", "r", stdin);
    scanf("%d", &t);
    while (t--) {
        init();
        ll ans = num[1] * num[n];
        for (int i = 1; i <= n; i++) {//检查对称乘起来是否相同,这样可以确定这个数是否存在
            if (ans != num[i] * num[n - i + 1]) {
                ans = -1;
                break;
            }
        }

        if (ans != -1) {//如果找到了这个数需要检验这个数的所有因子是否都在这n个数中
            for (int j = 1; j <= n; j++) {//对300个数进行因式分解
                ll temp = num[j];
                for (int i = 2; i * i <= temp; i++) {
                    if (temp % i == 0) {
                        if (!vis[i] || !vis[temp / i]) {
                            ans = -1;
                            break;
                        }
                    }
                }
                if (ans == -1) break;
            }
        }
        printf("%lld\n", ans);

        for(int i=1;i<=n;i++) vis[num[i]] = false;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值