思考する三角形▽

プログラミング初心者によるAtCoder解答解説

C - Train Ticket

コメント歓迎です。
前回同様、ビット全探索を使います。

方針

この問題では4桁の数字の間に'+'か'-'を入れて計算していきます。
計算結果が「7」なら指定のフォーマットで出力します。

数字は4桁なので数字の間は3箇所になります。
その3箇所に'+'か'-'のどちらかを入れていくので、2^3で全8パターンとなります。

8パターンを計算しながら、計算結果が「7」になったら出力処理に移るようにします。

ビット全探索の動作については前回の記事を参考にしてください。
前回:C - たくさんの数式 / Many Formulas - 思考する三角形▽


また、今回はvectorを使っています。
ベクターは配列に便利は機能が追加されたものと認識しています。

ちなみに今回は通常の配列でも問題なかったかもしれませんが、
vectorは配列の上位互換だと思っていますので基本的にvectorを使っています。
(間違っていたら教えてください。)

今回もシフト演算子を多用しています。
ようやくシフト演算自体に慣れてきた感じがしています。

コード(AC)

#include <iostream>
#include <vector>
using namespace std;

int main(){
  // 入力
  string ABCD;
  cin >> ABCD;

  // A, B, C, Dを個別の変数に定義
  int A, B, C, D;
  A = ABCD[0] - '0';
  B = ABCD[1] - '0';
  C = ABCD[2] - '0';
  D = ABCD[3] - '0';

  // A, B, C, Dをまとめたベクターを宣言
  vector<int> num = {A, B, C, D};
  // 出力用に'+', '-'の文字を要素とするベクターを宣言
  vector<char> op = {'+', '-'};

  // ビット全探索 ビットパターン 2^3 = 8
  for (int i = 0; i < (1 << 3); i++) {
    int sum = A;
    // ビットパターンと'+', '-'を関連付け
    // "0":'+'
    // "1":'-'
    for (int j = 0; j < 3; j++) {
      if (i >> j & 1) sum -= num[j + 1];
      else            sum += num[j + 1];
    }
    // 出力
    if (sum == 7) {
      cout << A;
      for (int k = 0; k < 3; k++) {
        // ビットパターンiからベクターopの文字を選択
        cout << op[(i >> k) & 1] << num[k + 1];
        if (k == 2) {
          cout << "=7" << endl;
          return 0;
        }
      }
    }
  }
}