第 14 回 - 組合わせ問題

[4/25, 2006 H.Aman]
67x27(1669bytes)   67x27(1669bytes) 【課題 3】

例題 3

617x44(19975bytes)

方針・アルゴリズム

A, B, C の個数についてさまざまな組合わせを作り,その合計が x となるかどうかを試していけばよい. つまり,この問題は例題 1, 例題 2 と同様の(所定の等式が成立するかどうかをチェックする)問題に帰着できる.

A, B, C の個数をそれぞれ a, b, c で表すと,次式が成立するような (a, b, c) を見つければよい:

142x14(2528bytes)
ただし,a, b, c の値は 0 以上 という制約しか設けられていないので, 各変数の上限を見つける必要がある.

いま,b, c = 0 とおくと,

50x32(1278bytes)
となるので,a の探索範囲は x/2 以下で十分であることが分かる.
同様にして b の探索範囲は x/5 以下,c の探索範囲は x/9 以下となる.
  • まず,x の値を読み込む. そして,a の値を 0 〜 x/2,b の値を 0 〜 x/5, c の値を 0 〜 x/9 の範囲で変化させながら, その都度 2a + 5b + 9c - x の値を計算し,0 と等しいかどうかを調べる.
80x16(888bytes) フローチャート

コーディング例

     1	/*
     2	 * プログラミング演習 第 14 回
     3	 * [例題 3]
     4	 * (C) 2006 Hirohisa AMAN <aman@cs.ehime-u.ac.jp, aman@computer.org>
     5	 */
     6	#include <stdio.h>
     7	
     8	int main(void){
     9	  int x, a, b, c;
    10	
    11	  /* x を読み込む */
    12	  printf("x = ? ");
    13	  scanf("%d", &x);
    14	
    15	  /* a, b, c を可能な範囲で変化させながら等号の成立をチェックする */
    16	  for ( a = 0; a <= x/2; a++ ){
    17	    for ( b = 0; b <= x/5; b++ ){
    18	      for ( c = 0; c <= x/9; c++ ){
    19	
    20		if ( 2*a + 5*b + 9*c - x == 0 ){
    21		  printf("%d %d %d\n", a, b, c);
    22		}
    23	
    24	      }
    25	    }
    26	  }
    27	
    28	  return 0;
    29	}
     
※左端の数字は行番号であり,ソースコードには含まれない点に注意!

コンパイル & 実行例

     $ gcc example14_3.c [Enter]
     $ ./a.out [Enter]
     x = ? 10 [Enter]
     0 2 0
     5 0 0