CSP-S 2021 回文

ad-hoc

结论:移除 \(n\) 个元素后,这些元素的另一个的位置一定是连在一起的。

如果移除一个元素 \(x\),设 \(x\) 的另一个位置为 \(x'\),如果 \(x'\) 不与其它已经移除的元素的另一个位置相连,那么它们之间一定隔着一些元素,并且这些元素是后来移除的元素的另一个位置,那么后面这些元素后面就无法对应移除。

分别判断先移除 \(a\) 的开头元素和末尾元素,后面每一步优先考虑移除开头元素,如果两段无法移除,则无解;移除完 \(n\) 个元素后,根据移除的顺序,剩下的顺序就能确定了。

时间复杂度为 \(O(n)\)

#include <bits/stdc++.h>

const int N = 500005;

int n, ano[N * 2];
int a[N * 2], b[N];
std::bitset<N * 2> s;

bool exist(int x) {
  return (s[ano[x] - 1] || s[ano[x] + 1]) && !s[x];
}

bool checkL() {
  s.reset();
  s[ano[1]] = 1;
  std::string res = "L";
  std::vector<int> pos = {1};
  int l = 2, r = n * 2;
  for (int i = 2; i <= n; i++) {
    if (exist(l)) {
      res.push_back('L');
      pos.push_back(l);
      s[ano[l]] = 1, l++;
    } else if (exist(r)) {
      res.push_back('R');
      pos.push_back(r);
      s[ano[r]] = 1, r--;
    } else {
      return false;
    }
  }
  std::reverse(pos.begin(), pos.end());
  for (auto x : pos) {
    if (s[ano[x] + 1]) {
      res.push_back('L');
    } else if (s[ano[x] - 1]) {
      res.push_back('R');
    } else {
      res.push_back('L');
    }
    s[ano[x]] = 0;
  }
  std::cout << res << '\n';
  return true;
}

bool checkR() {
  s.reset();
  s[ano[n * 2]] = 1;
  std::string res = "R";
  std::vector<int> pos = {n * 2};
  int l = 1, r = n * 2 - 1;
  for (int i = 2; i <= n; i++) {
    if (exist(l)) {
      res.push_back('L');
      pos.push_back(l);
      s[ano[l]] = 1, l++;
    } else if (exist(r)) {
      res.push_back('R');
      pos.push_back(r);
      s[ano[r]] = 1, r--;
    } else {
      return false;
    }
  }
  std::reverse(pos.begin(), pos.end());
  for (auto x : pos) {
    if (s[ano[x] + 1]) {
      res.push_back('L');
    } else if (s[ano[x] - 1]) {
      res.push_back('R');
    } else {
      res.push_back('L');
    }
    s[ano[x]] = 0;
  }
  std::cout << res << '\n';
  return true;
}

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  int t;
  std::cin >> t;
  while (t--) {
    std::cin >> n;
    for (int i = 1; i <= n * 2; i++) {
      std::cin >> a[i];
      if (b[a[i]]) {
        ano[i] = b[a[i]];
        ano[b[a[i]]] = i;
      }
      b[a[i]] = i;
    }
    if (!checkL() && !checkR())
      std::cout << -1 << '\n';
    for (int i = 1; i <= n * 2; i++)
      a[i] = 0, ano[i] = 0;
    for (int i = 1; i <= n; i++) b[i] = 0;
  }
  return 0;
}
posted @ 2024-10-05 00:29  Unino  阅读(12)  评论(0)    收藏  举报