Codeforces Round #673 (Div. 2) B
B. Two Arrays
我作为一个菜鸡,昨天居然把B题给做了出来,泪目QAQ.
于是就写个博客纪念一下。
题目链接:https://codeforces.ml/contest/1417/problem/B
题意:
首先定义:f(x)是在数组x取两个数组成数对(x[i], x[j]) 的个数,数对因满足 i ≠ j 且 x[i] + x[j] = T
题目要求:将一个数组分成a, b两部分,使得f(a) + f(b) 最小。
我的思路:
为了方便表述,假设0, 1数组以a, b数组代替。以
T
2
\frac{T}{2}
2T 为分界线,大于
T
2
\frac{T}{2}
2T 的数放到b, 反之放到a中, 这样就可以使f(a) 和 f(b)最小。但还会碰到一种情况, 数组中存在多个
T
2
\frac{T}{2}
2T ,为了保证结果最小,我们就可以将 这些数平分到a, b两个数组中。
下面是代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
typedef long long ll;
int a[N]; //a数组存放答案
ll t, n, k;
int main()
{
cin >> t;
while(t --)
{
int cnt = 0;
cin >> n >> k; //这里的k就是题目中的T
for(int i = 0; i < n; i ++)
{
int x; //依次输入数组的每一个元素,因为只用这一次,就不必开一个数组。
cin >> x;
if(2 * x == k) //尽可能的将多个 k/2 分开
{
a[i] = (cnt++) % 2;
continue;
}
if(x > k / 2) //以 k/2为分界线
a[i] = 1;
else
a[i] = 0;
}
for(int i = 0; i < n; i ++)
{
cout << a[i];
if(i < n - 1) cout << " ";
else cout << endl;
}
}
return 0;
}
昨天刚看到题的时候就感觉是贪心,在加上脑子灵光一现就稀里糊涂的写出来了