過去ログ

uchinyan
はい,こんにちは。さて,今回の問題は...
うーむ,具体的に試合のパターンを調べ規則性を見つけようとしたのですが,
うまくいかずはまってしまいました。
仕方がないので,必要条件を調べ,それが可能かプログラムを組みました。

まず,必要条件。数学ぽいですがごめんなさい。
1人が n 試合するとすると,条件より,参加者数は 3n+1 人,のはずです。
そこで,麻雀は4人で行うので,総試合数は,n(3n+1)/4 試合,のはずです。
これが整数になるはずなので,n は,4 の倍数又は 4 で割って 1 余る数,です。
つまり,n = 1, 4, 5, 8, 9, 12, ...,なので,
参加者数,3n+1 = 4, 13, 16, 25, 28, 37, ...,より,6番目は 37 人になります。
どうやら,この 37 人が答え,となっているようです。

ところが,問題はこの後。実際に実現できるかです。
よく分からなかったので,n 人の場合,参加者に 1 〜 n と番号を付け,
十進ベーシックで次のようなプログラムを組みました。

LET m = 40
DIM p(m,m), s(10000,4)

FOR n = 4 TO m
MAT p = ZER
LET cnt = 0
FOR a = 1 TO n-3
FOR b = a+1 TO n-2
LET f = 0
FOR c = b+1 TO n-1
FOR d = c+1 TO n
IF (p(a,b) + 1 <= 1) AND (p(a,c) + 1 <= 1) AND (p(a,d) + 1 <= 1) AND (p(b,c) + 1 <= 1) AND (p(b,d) + 1 <= 1) AND (p(c,d) + 1 <= 1) THEN
LET p(a,b) = p(a,b) + 1
LET p(a,c) = p(a,c) + 1
LET p(a,d) = p(a,d) + 1
LET p(b,c) = p(b,c) + 1
LET p(b,d) = p(b,d) + 1
LET p(c,d) = p(c,d) + 1
LET f = 1
LET cnt = cnt + 1
LET s(cnt,1) = a
LET s(cnt,2) = b
LET s(cnt,3) = c
LET s(cnt,4) = d
EXIT FOR
END IF
NEXT d
IF f = 1 THEN
EXIT FOR
END IF
NEXT c
NEXT b
NEXT a
LET f = 0
FOR i = 1 TO n-1
FOR j = i+1 TO n
IF p(i,j) < 1 THEN
LET f = 1
END IF
NEXT j
IF f = 1 THEN
EXIT FOR
END IF
NEXT i
IF f = 0 THEN
PRINT n
FOR i = 1 TO cnt
PRINT i; ":"; s(i,1); s(i,2); s(i,3); s(i,4)
NEXT i
REM FOR i = 1 TO n
REM FOR j = 1 TO n
REM PRINT p(i,j);
REM NEXT j
REM PRINT
REM NEXT i
END IF
NEXT n

END

結果は,

4
1 : 1 2 3 4
13
1 : 1 2 3 4
2 : 1 5 6 7
3 : 1 8 9 10
4 : 1 11 12 13
5 : 2 5 8 11
6 : 2 6 9 12
7 : 2 7 10 13
8 : 3 5 9 13
9 : 3 6 10 11
10 : 3 7 8 12
11 : 4 5 10 12
12 : 4 6 8 13
13 : 4 7 9 11

参加者数が,4 人と 13 人,の場合は問題なく解が得られたのですが,
16 人 〜 37 人の場合は解が得られません!

プログラムが間違っているのでしょうか?
訳が分からず悩んでおりました。

ごめんなさい。上記プログラムには誤り,というかチェック不足,がありました。
すべての可能な4人のパターンをチェックはしているのですが,
チェックの順番が単純すぎて一度失敗するとあきらめてしまうというミスを犯しました。
実際には,一度の失敗であきらめずにバックトラックして再度挑戦,のロジックが必要ですね。
大恥をかいてしまいましたが,自分への戒めのために,敢えて残しておきます。
   10月20日(木) 15:41:34     45400

過去問題一覧へ戻る