結果

問題 No.968 引き算をして門松列(その3)
ユーザー ngtkanangtkana
提出日時 2020-01-13 21:23:23
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 497 ms / 2,000 ms
コード長 4,711 bytes
コンパイル時間 2,104 ms
コンパイル使用メモリ 208,936 KB
実行使用メモリ 4,384 KB
最終ジャッジ日時 2023-08-24 14:14:23
合計ジャッジ時間 5,558 ms
ジャッジサーバーID
(参考情報)
judge11 / judge15
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,384 KB
testcase_01 AC 2 ms
4,376 KB
testcase_02 AC 2 ms
4,376 KB
testcase_03 AC 199 ms
4,376 KB
testcase_04 AC 203 ms
4,380 KB
testcase_05 AC 202 ms
4,380 KB
testcase_06 AC 202 ms
4,380 KB
testcase_07 AC 204 ms
4,380 KB
testcase_08 AC 318 ms
4,380 KB
testcase_09 AC 494 ms
4,380 KB
testcase_10 AC 497 ms
4,380 KB
testcase_11 AC 495 ms
4,376 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#define DEBUG 0
#include <bits/stdc++.h>
#define loop(n) for (lint ngtkana_is_a_genius = 0; ngtkana_is_a_genius < lint(n); ngtkana_is_a_genius++)
#define rep(i, begin, end) for (lint i = lint(begin); (i) < lint(end); i++)
#define all(v) v.begin(), v.end()
#define rand(l, r) std::uniform_int_distribution<>(l, r)(mt)
using lint = long long;
auto mt = std::mt19937_64(std::random_device{}());
auto cmn = [](auto&& a, auto b){ if (a > b) {a = b; return true;} return false; };
auto cmx = [](auto&& a, auto b){ if (a < b) {a = b; return true;} return false; };
void debug_impl() { std::cerr << std::endl; }
template <typename Head, typename... Tail>
void debug_impl(Head head, Tail... tail) { std::cerr << " " << head; debug_impl(tail...); }
#if DEBUG
#define debug(...)\
  do {\
    std::cerr << std::boolalpha << "[" << #__VA_ARGS__ << "]:";\
    debug_impl(__VA_ARGS__);\
    std::cerr << std::noboolalpha;\
  } while (false)
#else
#define debug(...) {}
#endif

template < typename Container, typename Value = typename Container::value_type, std::enable_if_t<!std::is_same< Container, std::string >::value, std::nullptr_t> = nullptr>
std::istream& operator>> (std::istream& is, Container& v)
  { for (auto & x : v) { is >> x; } return is; }

template < typename Container, typename Value = typename Container::value_type, std::enable_if_t<!std::is_same< Container, std::string >::value, std::nullptr_t> = nullptr >
std::ostream& operator<< (std::ostream& os, Container const& v) {
 os << "{";
  for (auto it = v.begin(); it != v.end(); it++)
    {os << (it != v.begin() ? "," : "") << *it;}
  return os << "}";
}

template < template < typename ... > class Tuple,  typename... Args, std::size_t ... Inds, std::size_t = std::tuple_size< Tuple < Args ... > >::value >
std::istream& tuple_input_impl(std::istream& os, Tuple<Args...>& tuple, std::integer_sequence<std::size_t, Inds...>)
  { (void)std::initializer_list<int>{((void)(os >> std::get< Inds >(tuple)), 0)...}; return os; }
template < template < typename ... > class Tuple,  typename... Args, std::size_t = std::tuple_size< Tuple < Args ... > >::value >
std::istream& operator>> (std::istream& os, Tuple<Args...>& tuple)
  { return tuple_input_impl(os, tuple, std::index_sequence_for<Args...>()); }

template < template < typename ... > class Tuple,  typename... Args, std::size_t ... Inds, std::size_t = std::tuple_size< Tuple < Args ... > >::value >
std::ostream& tuple_output_impl(std::ostream& os, const Tuple<Args...>& tuple, std::integer_sequence<std::size_t, Inds...>)
  { os << "("; (void)std::initializer_list<int>{((void)(os << (Inds > 0 ? "," : "") << std::get< Inds >(tuple)), 0)...}; return os << ")"; }
template < template < typename ... > class Tuple,  typename... Args, std::size_t = std::tuple_size< Tuple < Args ... > >::value >
std::ostream& operator<< (std::ostream& os, const Tuple<Args...>& tuple)
 { return tuple_output_impl(os, tuple, std::index_sequence_for<Args...>()); }

int main() {
  std::cin.tie(0); std::cin.sync_with_stdio(false);
  lint inf = std::numeric_limits<lint>::max();

  auto is_kadomatsu = [&] (lint a, lint b, lint c) {
    if (a <= 0 || b <= 0 || c <= 0) return false;
    if (a==b||b==c||c==a) return false;
    if (a > c) std::swap(a, c);
    return b < a || c < b;
  };

  lint sz = 3;
  lint q; std::cin >> q;
  loop(q) {
    std::vector<lint> a(sz), b(sz); std::cin>> a >> b;
    debug(a,b);

    auto cal = [&] (lint code_, auto a, auto b) {
      std::vector<lint> code;
      rep(i,0,4) {
        code.emplace_back(code_ % 4);
        code_ /= 4;
      }
      std::reverse(all(code));

      lint ans = 0;
      for (auto p : std::vector<std::pair<lint,lint>>{{code[0],code[1]},{code[2],code[3]}}) {
        lint x,y; std::tie(x,y) = p;
        if (x==3 || y==3 || x == y) continue;
        int z = 3 ^ x ^ y;
        lint& move = a.at(x);
        lint& target = a.at(y);
        lint& sacrifice = a.at(z);
        if (move < target) continue;
        int diff = move - target + 1;
        ans += diff * (b.at((y+1)%3));
        move -= diff;
        sacrifice -= diff;
      }
      if (!is_kadomatsu(a.at(0),a.at(1),a.at(2))) {
        ans = inf;
      }
      if (ans!=inf) {
        debug(a,b,ans);
      }
      return ans;
    };
    lint ans = inf;
    rep(i,0,256) {
      cmn(ans, cal(i, a, b));
    }
    if (ans == inf) ans = -1;
    std::cout << ans << std::endl;
  }
  return 0;
}

/*
誰かを道連れにして何かのすぐ下まで下げるをすればよいです。
下げるものは 2 つまでなので、全探索です。
1 回の操作は、4 bit で encode します。
前半が下げるもの、後半が目標です。
0,1,2 が添字で、3 はスキップです。
*/
0