順列の中で、もとの順番とまったく一致しないものを完全順列というらしい。これをもとめるアルゴリズムを考えてみた。もっと、無駄のない方法がありそうだ(Haskellなんかだと、数行ですむようですが)が、このへんで妥協してみた。
なお、何通りか表すのがモンモール数というらしく、こちらは漸化式がWikiにあったので、それをもとにすぐ作ることができた。
#include "stdafx.h"
#include <iostream>
using namespace std;
const int imax=5;
int lst[imax],kekka[imax];
void shori(int level);
double shori2(int level);
int coun;
int _tmain(int argc, _TCHAR* argv[])
{
coun=0;
int i;
cout<<endl<<"全部で"<<shori2(imax)<<endl;
for (i=0;i<imax;i++){
kekka[i]=-1;
}
shori(0);
char dummy[1];
cin>>dummy;
return 0;
}
double shori2(int level) {//モンモール数
double x;
if(level>2){
x=(level-1)*(shori2(level-1)+shori2(level-2));
}
else{
if(level==1) x=0;
if(level==2) x=1;
}
return x;
}
void shori(int level) {//完全順列
int i,ii;
bool flg;
for(ii=0;ii<imax;++ii){
flg=true;
for(i=0;i<level;i++){
if(kekka[i]==ii){
flg=false;//親ですでに使われていないかチェック
break;
}
}
if(level!=ii && flg) {//同じ順番で親でないときはOK
kekka[level]=ii;//ここでいったん確定
if (level==imax-1){//最深レベルで出力
for(i=0;i<imax;i++){
printf("%d ", kekka[i]);
}
printf("=No.%d\n",coun) ;
coun=coun+1;
}
shori(level+1);
kekka[level]=-1;
}
}
}
0 件のコメント:
コメントを投稿