AcWing第34轮周赛T3 序列重排

本文探讨了AcWing第34轮周赛的第三题,该题目要求对给定序列进行重排,确保每个元素(除第一个外)是前一个元素的两倍或三分之一。题目保证一定有解。解题策略涉及对序列进行双关键字排序,根据因子2和因子3的数量来确定序列的正确顺序。
摘要由CSDN通过智能技术生成

给定一个长度为 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 2n10
所有测试点满足 2 ≤ n ≤ 100 , 1 ≤ a i ≤ 3 × 1 0 18 2≤n≤100,1≤a_i≤3×10^{18} 2n1001ai3×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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值