题目:
题目描述:
给你一个长度为 n 的 a 数组,你需要构造一个等长 b 数组,构造要求如下:
①
② 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 的范围内,那我 ③ 条件就能满足。也就是
再找在这个区间内怎么满足 ② 条件?如何确保对于不同 ai 的所形成的 bi 取值范围,b 数组中相邻的数都能有一方整除另一方?
从特例的角度来想,我先想到的是 2 的幂,而且经过验证发现是可行的:
1. 对于任意的 ai ,在 范围内,必然有一个 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;
}