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 <stdio.h>
- #include <math.h>
- 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;
- }
- </math.h></stdio.h>