题目 | Add, Divide and Floor
Educational Codeforces Round 158 (Rated for Div. 2)
C. Add, Divide and Floor
https://codeforces.com/contest/1901/problem/C
2 seconds / 256 megabytes
standard input / standard output
Problem
You are given an integer array
Print the smallest number of operations required to make all elements of the array equal.
If the number of operations is less than or equal to
Input
The first line contains a single integer
The first line of each testcase contains a single integer
The second line contains
The sum of
Output
For each testcase, print the smallest number of operations required to make all elements of the array equal.
If the number of operations is less than or equal to
Example
Input
4
1
10
2
4 6
6
2 1 2 1 2 1
2
0 32
Output
0
2
2 5
1
1
6
Note
In the first testcase, all elements are already equal, so
In the second testcase, you can't make less than
In the last testcase, you can't make less than
题解
本题重点是要找到关键性质来简化问题,否则问题会变得很麻烦。
仅考虑最大最小值即可
显然,对数列中每个数字
同时,对数列中每个数字
综上,题目给出的
仅考虑
对于两个不相等的数,对于它们之间的不同的二进制位,我们是不可能通过同时
对于数
那么更改一下顺序,实际上上面这个操作就是先进行两次
因此,操作都可以转换成
操作策略
我们只观察二进制最低位:
- 如果它们相同,那么进行
的操作即可。 - 如果最大值为
,最小值为 ,那么进行 的操作。 - 如果最大值为
,最小值为 ,那么进行 的操作。
这样操作的原因是,
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
void solve()
{
int n;
cin >> n;
int mx = 0, mn = INT32_MAX;
for (int i = 0; i < n; i++)
{
int t;
cin >> t;
mx = max(mx, t);
mn = min(mn, t);
}
int ans = 0, add = 0;
vector<int> op;
while (mx != mn)
{
if (mx % 2 == mn % 2)
add = 0;
else if (mx % 2 == 0)
add = 1;
else
add = 0;
mx = (mx + add) / 2;
mn = (mn + add) / 2;
op.push_back(add);
ans++;
}
cout << ans << endl;
if (0 < ans && ans <= n)
{
for (auto &ele : op)
cout << ele << ' ';
cout << endl;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while (t--)
solve();
return 0;
}
本文采用 CC BY-SA 4.0 许可,本文 Markdown 源码:Haotian-BiJi