给定一个长度为 n 的整数序列
a
1
,
a
2
,
…
,
a
n
a_1,a_2,…,a_n
a1,a2,…,an。
请你对序列进行重新排序(也可以保持原序列),要求新序列满足每个元素(第 1 个除外)都恰好是前一个元素的两倍或前一个元素的三分之一。
保证输入一定有解。
输入格式
第一行包含整数
n
n
n。
第二行包含 n n n 个整数 a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,…,an
输出格式
一行
n
n
n 个整数,表示排序后的序列。输出任意合法方案即可。
数据范围
前三个测试点满足
2
≤
n
≤
10
2≤n≤10
2≤n≤10。
所有测试点满足
2
≤
n
≤
100
,
1
≤
a
i
≤
3
×
1
0
18
2≤n≤100,1≤a_i≤3×10^{18}
2≤n≤100,1≤ai≤3×1018。
分析 根据题目描述,能把所有数分为两部分,一部分是存在因子为2的,另一部分是存在为因子3的;
在保证有解的前提下
设xi表示第i个数 因子2的数量
设yi表示第i个数 因子3的数量
那么对于如果序列存在则xi < x(i+1) 或者 xi = x(i+1) 且 yi > y(i+1)
又因为任意两个数都不相同 因此不存在xi == xj 且 yi = yj, 所以充分性成立
因此考虑双关键字排序
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 110;
pair<pair<int , int> , int> q[N];
int n;
int get(int x , int i)
{
int res = 0;
while(x % i == 0) res ++ , x /= i;
return res;
}
signed main()
{
cin >> n;
for(int i = 1; i <= n; ++ i)
{
int x;
cin >> x;
q[i] = {{get(x , 2) , -get(x , 3)} , x};
}
sort(q + 1 , q + n + 1);
for (int i = 1; i <= n; ++ i) cout << q[i].second << " ";
return 0;
}