AtCoder BC 071 D: Coloring Dominoes
問題
https://beta.atcoder.jp/contests/abc071/tasks/arc081_b
解法
左から順にドミノの並びを見ていく場合、並び方は
・縦に1つ置く ・横に2つ重ねる
の2パターンです。
そこで、直前の並びに対する次の並びでの塗り方のパターンを考えます。
・「縦に1つ」→ 「縦に1つ」 直前の色以外の2色が選べる = 2通り
・「縦に1つ」→ 「横に2つ」 直前の色以外の2色について、どちらかを上、どちらかを下にする = 2通り
・「横に2つ」→ 「縦に1つ」 必ず直前の色以外の1色を選ぶことになる = 1通り
・「横に2つ」→ 「横に2つ」 上に直前の上下の2色以外を選ぶ場合、下は必ず直前の上の色になる = 1通り 上に直前の下の色を選ぶ場合、下は残りの2色を選べる = 2通り 合わせて3通りとなる
また、一番左側のドミノについては、
・「縦に1つ」= 3通り ・「横に2つ」= 3 x 2 = 6通り
となる。
よって、左側から順番にドミノの並びを検査していき、上記のパターンをかけていくと解ける。(毎回MODをとることを忘れない)
実装
#include<iostream> #include<algorithm> #include<string> #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define REP(i,n) FOR(i,0,n) #define MOD 1000000007 using namespace std; typedef long long int ll; const ll INF=(ll)1e18; int main(){ int N; cin >> N; string s1, s2; cin >> s1 >> s2; int i = 0; ll ans = 0; int flag; if(s1[i] == s2[i]){ ans = 3; i += 1; flag = 1; }else{ ans = 6; i += 2; flag = 2; } while(i < N){ if(s1[i] == s2[i]){ if(flag == 1){ ans *= 2; ans %= MOD; } i += 1; flag = 1; }else{ if(flag == 1){ ans *= 2; ans %= MOD; }else{ ans *= 3; ans %= MOD; } i += 2; flag = 2; } } cout << ans << endl; }