ながめも

競技プログラミングについて

AtCoder ABC114 C-755 深さ優先探索

ABC114 C-755

初めて深さ優先探索Depth-First Search)を書いたのでブログに書きます。(なんとなく)
問題は以下。

atcoder.jp

実行時間制限: 2 sec / メモリ制限: 1024 MB
配点 : 300点

問題文
整数 N が与えられます。1 以上 N 以下の整数のうち、七五三数 は何個あるでしょうか?

ここで、七五三数とは以下の条件を満たす正の整数です。

十進法で表記したとき、数字 7, 5, 3 がそれぞれ 1 回以上現れ、これら以外の数字は現れない。

制約
1≤N<10^9
Nは整数である。


〜考え方〜
9桁なので、それぞれの桁が3 or 5 or 7の場合を全て調べても3^9で済む。
全列挙は深さ優先探索を用いる(本番解いたときは直積とか使って無理矢理数えた)。
7,5,4がそれぞれ一回以上現れないといけないので、それをどう表現するかが少し悩みどころ。
a,b,cの初期値を0(false)にしておいて、
3が出たらaを1に変更、
5が出たらbを1に、
7が出たらcを1にという風にしたあと、
a&b&cを取るときれいに書けるっぽい。
単純に数えてもいいけど、無駄も多そう。
あとans++する前にx<=Nを考えておく。

変数の宣言をどこにするかがまだ悩むけど、たぶんdfsとmainで共通のやつはその外で定義して、
dfs内だけで使うやつは引数のところでいいのかな。たぶん。

コードは以下。

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

ll N;
int ans = 0;
void dfs(ll x,int a,int b,int c){
	if(x>N) return;
	if(a&b&c)ans++;
	dfs(10*x+3,1,b,c);
	dfs(10*x+5,a,1,c);
	dfs(10*x+7,a,b,1);
}

int main() {
	cin>>N;
	dfs(0,0,0,0);
	cout<<ans<<endl;
}