目录
题目:
题目理解:
给你长度为 n 的数组,你需要将原数组分成两组,这两组的不幸值的和是所有分组情况的最低。
不幸值:组中( 任意两个不重叠的位置的数值的和等于题目所给的 T )的个数
你需要返回一个与原数组等长的 01数组,代表着原数组如何分成两组(位置上为 0 的一组,位置上为 1 的另一组)
思路:
首先想一个问题,什么时候才能让组中任意两个的和尽可能不等于 T?
不难想到要么组里面的数都特别大,或者都特别小的时候就可以,那么边界在哪里?就是 T ÷ 2 。
再加上题目并没有要求两个组是否要均匀分配,那么我们可以进行如下操作:
①严格小于 T ÷ 2 的分为一组,这样这个组内任意两个的和都必小于 T ,
②严格大于 T ÷ 2 的放到另一组,这样这个组内任意两个的和都必大于 T
③严格等于 T ÷ 2 的尽可能的均匀分到两个组,这样只有当一个组内有多个(严格等于 T ÷ 2 )的元素的时候才会有不幸值,且此时不幸值最少
思路有了,具体操作请看AC代码:
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
int a[N];//原数组
int b[N];//分配后的数组
int main()
{
std::ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
int n, k;
cin >> n >> k;
for (int i = 1; i <= n; i++)
cin >> a[i];
int flag = 0;//用于平均分配( 严格等于 T ÷ 2 )的情况
for (int i = 1; i <= n; i++)
{
if (a[i] + a[i] < k)//( 严格小于 T ÷ 2 )的情况
b[i] = 1;
else if (a[i] + a[i] > k)//( 严格大于 T ÷ 2 )的情况
b[i] = 0;
else//( 严格等于 T ÷ 2 )的情况
{
if (flag)
{
flag = 0;
b[i] = 1;
}
else
{
flag = 1;
b[i] = 0;
}
}
}
for (int i = 1; i <= n; i++)
cout << b[i] << " ";
cout << '\n';
}
return 0;
}