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;
}