2018 年度「計算数学a」「同b」やや難しい問題

時間に余裕のある人のための,やや難しいと思われる問題です。

たぶん,前半で習った C 言語の範囲で書けると思います。

この授業ではポインタを扱わないので,以下の問題には, ポインタを知っていれば別の書き方がある,というものが含まれます。

インターネットを検索すればどこかに答えがあると思いますが, 自分で考えることを楽しんでください。

0 から N-1 までの並べ替え(その1)

授業でやったように,次のように始まるプログラムです。

#include <stdio.h>

#define N 4

int a[N];

0 から N-1 までの整数を並べ替えると, N! 通りの数字列が得られます。 これらを辞書式順序に並べて,順に 0 番め,1 番め,……,N! - 1 番め, とします。 何番めかを指定すると,配列 a[ ] にそれをセットする関数を書きなさい。

くわしく言うと次のようになります。 N が 4 の場合,0 番めとすると a[0], a[1], a[2], a[3] が順に 0, 1, 2, 3 となり,1 番めとすると 0, 1, 3, 2 となり,……, 22 番めとすると 3, 2, 0, 1 となり, 23 番めとすると 3, 2, 1, 0 となる関数を書きなさい。

N を 4 にして書いてみるのがよいでしょう。 main() では,次のように出力させます。

    0: 0123
    1: 0132
    2: 0213
      ...
   22: 3201
   23: 3210

ここの int 型では 12! までが使えるので, N を 12 にしての実験は可能です。 その場合,printf() の中の %d%x とすると, 出力が十六進になりますので,10 は a, 11 は b と,一桁で表示され便利です。 (ただし,全部出力させるには非常に長い時間がかかります。)

行列式の値を定義に従って計算するプログラム

上のプログラムでは,N 個の元の,すべての置換が得られます。 それの応用として,行列式の値を定義に従って計算するプログラムを書きなさい。

その場合,行列は,二重配列の初期化を利用して指定するとよいでしょう。

置換の符号は,転倒数が奇数なら -1, 偶数なら +1 として計算するのが速いでしょう。 転倒数の定義は集合 {(i, j) | i < j かつ σ(i) > σ(j)} の元の数です。

0 から N-1 までの並べ替え(その2)

「その1」の“逆関数”を書きなさい。 つまり,配列 a[ ] をセットしてその関数を呼ぶと, それが何番めかを返す関数を書きなさい。

0 から N-1 までの並べ替え(その3)

配列 a[ ] に 0 から N - 1 までの整数の並べ替えをセットして呼ぶと, 辞書式順序でその次のものになるよう,a[ ] を変えるプログラムを書きなさい。 返り値は,成功すれば 1, 失敗すれば(すでに最大のものがセットされている場合) 0 を返す,としなさい。

これは,単にその1とその2の組み合わせではありません。 N が 13 以上でも動くように書きなさい。 (プログラムを書いている間は,N はもっと小さくてよいでしょう。)


岩瀬順一