2つの文字 A, B を使って作られる長さ 15 の順列のうち次の条件を満たすものは何個あるか.1991年数オリ予選より
条件: 「連続する2文字の (順序) 対として AA が 5 回, AB, BA, BB が各 3 回現れる.」
例えば順列 AABBAAAABAABBBB は, AA が 5 回, AB が 3 回, BA が 2回, BB が 4 回現れるので, 上の条件を満たしていない.
解けなかったので、悔しいから(&ヒマだから)プログラムで。
解答の方針はA→B、B→Aと変わる所に注目して、
ABとBAが3回出現するから
Aの”カタマリ”をa,Bのカタマリをbとすると、有り得るのは
abababa
または
bababab
の2つの場合。
両方を数え上げればおk(980通り)
細かい解説は多分どこかにあるんで検索してください。
んで、一般化したときに(上の条件はAとBだけで、4パターン全て出てる。ABCで作った列で、AB,ACが1回ずつある時のみカウントとか)力技以外で解く方法とかあるのかにゃ?
#include#include int N=15; int chk(int a[]){ int cntAA=0; int cntBB=0; int cntBA=0; int cntAB=0; for(int i=1;i<=N-1;i++){ if(a[i]==0 && a[i+1]==0) cntAA++; if(a[i]==0 && a[i+1]==1) cntAB++; if(a[i]==1 && a[i+1]==0) cntBA++; if(a[i]==1 && a[i+1]==1) cntBB++; } if(cntAA==5 && cntAB==3 && cntBA==3 && cntBB==3){ return 1; }else{ return 0; } } int main(void) { int a[N+1]; int count=0; int MAX=pow(2,15)-1; for(int n=0;n<=MAX;n++){ //10進数→2進数 for(int i=1;i<=N;i++) a[i]=(n/(int)pow(2,i-1))%2; if(chk(a))count++; } printf("%d",count); return 0; }