Submission #1083506

#TimeUsernameProblemLanguageResultExecution timeMemory
1083506avighnaMutating DNA (IOI21_dna)C++17
50 / 100
1562 ms8412 KiB
#include "dna.h"
#include <algorithm>
#include <numeric>
#include <set>
#include <vector>

#include <iostream>

std::vector<int> psums[9];
const std::vector<std::string> poss = {"AT", "AC", "TC", "TA", "CA", "CT"};
const std::vector<std::string> poss_exh = {"AT", "AC", "TC", "TA", "CA",
                                           "CT", "AA", "TT", "CC"};
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::vector<int> A_psum[3], B_psum[3];
std::vector<std::string> to_permute = {"ATTCCA", "ACCTTA", "TCCAAT",
                                       "TAACCT", "CAATTC", "CTTAAC"};

int gi(char c) {
  for (int i = 0; i < letters.size(); ++i) {
    if (c == letters[i]) {
      return i;
    }
  }
  return -1;
}

int gi(std::string str) {
  for (int i = 0; i < poss_exh.size(); ++i) {
    if (str == poss_exh[i]) {
      return i;
    }
  }
  return -1;
}

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

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

int get_distance(int x, int y) {
  ++x, ++y;
  for (auto &ch : letters) {
    if (A_psum[gi(ch)][y] - A_psum[gi(ch)][x - 1] !=
        B_psum[gi(ch)][y] - B_psum[gi(ch)][x - 1]) {
      return -1;
    }
  }
  std::vector<int> sums(9);
  for (auto &p : poss) {
    sums[gi(p)] = psums[gi(p)][y] - psums[gi(p)][x - 1];
  }
  int ans = 0;
  for (auto &[u, v] : complements) {
    int cur = std::min(sums[gi(u)], sums[gi(v)]);
    ans += cur;
    sums[gi(u)] -= cur, sums[gi(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[gi(a)], mp[gi(b)], mp[gi(c)]});
      cur_ans += 2 * cur;
      mp[gi(a)] -= cur, mp[gi(b)] -= cur, mp[gi(c)] -= cur;
    }
    final_ans = std::min(final_ans, cur_ans);
  } while (std::next_permutation(to_permute.begin(), to_permute.end()));
  return final_ans;
}

Compilation message (stderr)

dna.cpp: In function 'int gi(char)':
dna.cpp:22:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   22 |   for (int i = 0; i < letters.size(); ++i) {
      |                   ~~^~~~~~~~~~~~~~~~
dna.cpp: In function 'int gi(std::string)':
dna.cpp:31:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::__cxx11::basic_string<char> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   31 |   for (int i = 0; i < poss_exh.size(); ++i) {
      |                   ~~^~~~~~~~~~~~~~~~~
#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...