(用心诠释什么叫心态炸裂)
原题
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标记一下,如果减少过了就不要让它减少了。
最后,降序遍历,找到的第一个就是目标数