codefoeces 题目 Find The Array

题目:

题目描述:

给你一个长度为 n 的 a 数组,你需要构造一个等长 b 数组,构造要求如下:

① 1\leq b_i\leq 1e9

② b 数组中任意相邻两个数,至少有一方可以整除另一方

③ 即 a 数组与 b 数组对位的差的绝对值的和,要小于等于 a 数组总和的一半

思路:

先从感觉复杂的条件 ③ 入手,因为往往条件复杂的特例会带来很多信息。如果这个条件要成立,说明 b 的每一位不能和 a 的对应位置数值相差太大。将 2 挪到右边,说明差的绝对值求和公式总和要小于等于( S / 2  )。

不难想到:

S = a1 + a2 + a3 + ... + an

S/2 = a1/2 + a2/2 + a3/2 + ... + an/2

如果再用一种均衡的思想,将 S/2 分配到每一位,如果我们能将第 i 个绝对值也就是 ai 与 bi 的差值控制在上下 ai/2 的范围内,那我 ③ 条件就能满足。也就是

(1/2 * a_i )\leq b_i \leq (3/2 * a_i)

再找在这个区间内怎么满足 ② 条件?如何确保对于不同 ai 的所形成的 bi 取值范围,b 数组中相邻的数都能有一方整除另一方?

从特例的角度来想,我先想到的是 2 的幂,而且经过验证发现是可行的:

1. 对于任意的 ai ,在 (1/2 * a_i )\leq x \leq a_i 范围内,必然有一个 2 的幂数,条件 ③ 成立

2. 对于任意两个2的幂,必然存在整除关系,条件 ② 成立

思路有了,具体操作请看AC代码:

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N =50 + 5;
const int inf = 2e9 + 5;

ll a[N];

void solve()
{
	int n;
	cin >> n;

	for (int i = 1; i <= n; i++)
		cin >> a[i];

	for (int i = 1; i <= n; i++)
	{
		ll temp = 1;
		while (temp <= a[i])
			temp <<= 1;
		cout << temp/2 << " ";
	}
	cout << '\n';
}

int main()
{
	std::ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	int t; cin >> t;
	while (t--)
		solve();
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值