Submission #1083498

#TimeUsernameProblemLanguageResultExecution timeMemory
1083498avighnaMutating DNA (IOI21_dna)C++17
50 / 100
1557 ms9816 KiB
#include "dna.h"
#include <algorithm>
#include <map>
#include <numeric>
#include <set>
#include <vector>

std::map<std::string, std::vector<int>> psums;
const std::vector<std::string> poss = {"AT", "AC", "TC", "TA", "CA", "CT"};
const std::vector<std::pair<std::string, std::string>> complements = {
    {"AT", "TA"}, {"AC", "CA"}, {"TC", "CT"}};
const std::vector<char> letters = {'A', 'T', 'C'};
int n;
std::map<char, std::vector<int>> A_psum, B_psum;
std::vector<std::string> to_permute;

void init(std::string a, std::string b) {
  n = a.length();
  for (auto &p : poss) {
    psums[p].resize(n + 1);
  }
  for (auto &c : letters) {
    A_psum[c].resize(n + 1);
    B_psum[c].resize(n + 1);
    psums[std::string(2, c)].resize(n + 1);
  }
  a = " " + a;
  b = " " + b;
  for (int i = 1; i <= n; ++i) {
    psums[std::string(1, a[i]) + std::string(1, b[i])][i]++;
    A_psum[a[i]][i]++;
    B_psum[b[i]][i]++;
  }

  for (auto &p : psums) {
    std::vector<int> res(p.second.size());
    std::partial_sum(p.second.begin(), p.second.end(), res.begin());
    p.second = res;
  }
  for (auto &p : A_psum) {
    std::vector<int> res(p.second.size());
    std::partial_sum(p.second.begin(), p.second.end(), res.begin());
    p.second = res;
  }
  for (auto &p : B_psum) {
    std::vector<int> res(p.second.size());
    std::partial_sum(p.second.begin(), p.second.end(), res.begin());
    p.second = res;
  }

  std::set<std::string> st;
  for (int i = 0; i < 6; ++i) {
    for (int j = 0; j < 6; ++j) {
      for (int k = 0; k < 6; ++k) {
        if (i == j or j == k or i == k) {
          continue;
        }
        if (poss[i][1] == poss[j][0] and poss[j][1] == poss[k][0] and
            poss[k][1] == poss[i][0]) {
          st.insert(poss[i] + poss[j] + poss[k]);
        }
      }
    }
  }
  for (auto &s : st) {
    to_permute.push_back(s);
  }
}

int get_distance(int x, int y) {
  ++x, ++y;
  for (auto &ch : letters) {
    if (A_psum[ch][y] - A_psum[ch][x - 1] !=
        B_psum[ch][y] - B_psum[ch][x - 1]) {
      return -1;
    }
  }
  std::map<std::string, int> sums;
  for (auto &p : poss) {
    sums[p] = psums[p][y] - psums[p][x - 1];
  }
  int ans = 0;
  for (auto &[u, v] : complements) {
    int cur = std::min(sums[u], sums[v]);
    ans += cur;
    sums[u] -= cur, sums[v] -= cur;
  }
  std::sort(to_permute.begin(), to_permute.end());
  int final_ans = 1e9;
  do {
    auto mp = sums;
    auto cur_ans = ans;
    for (auto &s : to_permute) {
      auto a = s.substr(0, 2);
      auto b = s.substr(2, 2);
      auto c = s.substr(4, 2);
      int cur = std::min({mp[a], mp[b], mp[c]});
      cur_ans += 2 * cur;
      mp[a] -= cur, mp[b] -= cur, mp[c] -= cur;
    }
    final_ans = std::min(final_ans, cur_ans);
  } while (std::next_permutation(to_permute.begin(), to_permute.end()));
  return final_ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...