L. Grayscale Confusion
考虑采用线性函数 f(r, g, b) = x*r + y*g + z*b
,对 RGB 的系数和为一且均非负。
可以发现,只有 RGB 各自增 1 才能满足偏序,因此所有满足偏序的颜色对都能被区分开。
对于需要混淆的两个颜色:
如果有 RGB 中的一者相等,假设是 R 相等,直接令系数为 (1, 0, 0)。
如果满足偏序关系,则寄掉。
否则一定存在交错,假设 ,
,令
,
,那么令:
x = q / (p + q)
y = p / (p + q)
z = 0
就可以实现混淆这两个颜色。
因此可以这样编码:
#include <cmath>
#include <iostream>
#define int long long
const int N = 1e3 + 4;
int n, c[N][3];
double f[3];
void goodbye() {
for (int i = 0; i < n; i++) {
double res = 0;
for (int j = 0; j < 3; j++) {
res += f[j] * c[i][j];
}
std::cout << std::lround(res) << '\n';
}
}
void ohno() { std::cout << -1 << '\n'; }
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
std::cin >> n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < 3; j++) {
std::cin >> c[i][j];
}
}
// find pos, a = b
int eq = -1;
for (int i = 0; i < 3; i++) {
if (c[0][i] == c[1][i]) {
eq = i;
break;
}
}
// exist eq, naive
if (eq != -1) {
f[eq] = 1;
goodbye();
return 0;
}
// find pos, a < b, a > b
int lt = -1, gt = -1;
for (int i = 0; i < 3; i++) {
if (c[0][i] < c[1][i]) {
lt = i;
} else {
gt = i;
}
}
// ordered, ohno
if (lt == -1 || gt == -1) {
ohno();
return 0;
}
int dl = c[1][lt] - c[0][lt];
int dg = c[0][gt] - c[1][gt];
f[gt] = (double)dl / (dl + dg);
f[lt] = (double)dg / (dl + dg);
goodbye();
return 0;
}