AtCoder ABC 114 C - 755 再帰関数 整数操作

不正解問題

問題概要

10 進法表記で各桁の値が 7 と 5 と 3 のみで、かつ 7, 5, 3 がすべて一度以上は登場するような数を「753 数」と呼ぶことにする。
整数 N が与えられて、N 以下の 753 数が何個あるかを求めよ。

制約

1≤N≤10^9

考えたこと(WA)

合計値のreturnを最下層でやってればなんとかなるんじゃね..あれ?できない..
やっぱり値は関数に渡しとかないといけないのかな?
3,5,7を整数で操作するのはむりだから、配列つかってあとで整数に変換しよ..
うーん、意味わからんくなった


#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;

int N;

int loop(int N, vector<int>A, int bit) {
	if (N < pow(10, (A.size() - 1))) {
		string str;
		for (int i = 0; i < A.size(); i++) {
			str += to_string(A[i]);
		}
		long long num = stoi(str);
		if (N <= num) {
			return 0;
		}
	}
	int sum = 0;

	if (bit == 7) {
		sum++;
	}

	A.push_back(3);
	bit |= (0 << 1);
	sum += loop(N, A, bit);
	A.pop_back();
	A.push_back(5);
	bit |= (1 << 1);
	sum += loop(N, A, bit);
	A.pop_back();
	A.push_back(7);
	bit |= (2 << 1);
	sum += loop(N, A, bit);
	A.pop_back();

	return sum;
}

int main() {
	cin >> N;
	vector<int>A;
	int bit = 0;
	int num = loop(N, A, bit);
	cout << num;
}

サイトのコードを見て考えたこと、理解したこと

  • 整数で操作するのは無理だと思っていたが、全然そんなことなかった。num * 10 + nでどうとでもなる。すごい。
  • main関数の方でカウント変数を初期化しておいて、関数funcに渡して増やさせていた。この発想は大事だと思った。
  • 2進数は0b000..みたいに直接書くことができるらしい。知らんかったw
#include <iostream>
using namespace std;

// 入力
long long N;

// cur: 現在の値、use: 7, 5, 3 のうちどれを使ったか, counter: 答え
void func(long long cur, int use, long long &counter){
    if (cur > N) return; // ベースケース
    if (use == 0b111) ++counter; // 答えを増やす

    // 7 を付け加える
    func(cur * 10 + 7, use | 0b001, counter);

    // 5 を付け加える
    func(cur * 10 + 5, use | 0b010, counter);

    // 3 を付け加える
    func(cur * 10 + 3, use | 0b100, counter);
}

int main() {
    cin >> N;
    long long res = 0;
    func(0, 0, res);
    cout << res << endl;
}


一回目です。