時間に余裕のある人のための,やや難しいと思われる問題です。
たぶん,前半で習った C 言語の範囲で書けると思います。
この授業ではポインタを扱わないので,以下の問題には, ポインタを知っていれば別の書き方がある,というものが含まれます。
インターネットを検索すればどこかに答えがあると思いますが, 自分で考えることを楽しんでください。
授業でやったように,次のように始まるプログラムです。
#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)} の元の数です。
「その1」の“逆関数”を書きなさい。 つまり,配列 a[ ] をセットしてその関数を呼ぶと, それが何番めかを返す関数を書きなさい。
配列 a[ ] に 0 から N - 1 までの整数の並べ替えをセットして呼ぶと, 辞書式順序でその次のものになるよう,a[ ] を変えるプログラムを書きなさい。 返り値は,成功すれば 1, 失敗すれば(すでに最大のものがセットされている場合) 0 を返す,としなさい。
これは,単にその1とその2の組み合わせではありません。 N が 13 以上でも動くように書きなさい。 (プログラムを書いている間は,N はもっと小さくてよいでしょう。)