cf 535 div3 B 题解

(用心诠释什么叫心态炸裂)
原题
Recently you have received two positive integer numbers x and y. You forgot them, but you remembered a shuffled list containing all divisors of x (including 1 and x) and all divisors of y (including 1 and y). If d is a divisor of both numbers x and y at the same time, there are two occurrences of d in the list.

For example, if x=4 and y=6 then the given list can be any permutation of the list [1,2,4,1,2,3,6]. Some of the possible lists are: [1,1,2,4,6,3,2], [4,6,1,1,2,3,2] or [1,6,3,2,4,1,2].

Your problem is to restore suitable positive integer numbers x and y that would yield the same list of divisors (possibly in different order).

It is guaranteed that the answer exists, i.e. the given list of divisors corresponds to some positive integers x and y.

Input
The first line contains one integer n (2≤n≤128) — the number of divisors of x and y.

The second line of the input contains n integers d1,d2,…,dn (1≤di≤104), where di is either divisor of x or divisor of y. If a number is divisor of both numbers x and y then there are two copies of this number in the list.

Output
Print two positive integer numbers x and y — such numbers that merged list of their divisors is the permutation of the given list of integers. It is guaranteed that the answer exists.

题意
给了多个数,它们是某两个数的全部约数,求出这两个数

题解
(打眼一看,简单,十分简单,结果自己把自己作的痛不欲生,直到打了自己一巴掌才反应过来)
首先,不难发现,全部约数意味着1要出现,那么sort一下,最大的元素必定是一个目标数,之后,只需要算另外一个数就可以了。很简单,唯一可能有坑的点是有的数是公约数,意味着它会出现两次,那么我们需要一个标记数组,如果这个数被除过了,那么下次就不让它标记,这样就可以完整的算出一个数的全部约数,然后取剩下数中未标记的最大的数,就是另外一个目标数了

#include <bits/stdc++.h>
using namespace std;
int c[10004];
int b[10004];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n,i,j;
    int a[200];
    memset(c,0,sizeof(c));
    memset(b,0,sizeof(b));
    cin>>n;
    for(i=1;i<=n;i++)
        {
            cin>>a[i];
            c[a[i]]++;
        }
    sort(a+1,a+n+1);
    int k,t;
    if(n==1)cout<<a[1]<<endl;
    else{
    t=a[n];
    for(i=1;i<=n-1;i++){
        if(t%a[i]==0){
            if(c[a[i]]==2) {
                c[a[i]]--;
                b[a[i]]++;
            }
            if(c[a[i]]==1&&b[a[i]]!=1){
                c[a[i]]--;
            }
        }
    }
    for(i=n-1;i>=0;i--){
        if(c[a[i]]==1){
            k=a[i];
            break;
        }
    }
    cout<<max(k,t)<<" "<<min(k,t)<<endl;
    }
    return 0;
}

这里开了两个标记数组,数组c用来统计次数,就是把出现两次的减少一次,出现一次的减少为0,但是,直接这样的话会把2直接变成0,所以再用数组b标记一下,如果减少过了就不要让它减少了。
最后,降序遍历,找到的第一个就是目标数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值