トップページに戻る
次のPHPのサンプルへ
前のPHPのサンプルへ
Q13 並べ替えの繰り返し2
PHPのソース
<?php
ini_set('memory_limit', '256M');
Solve(4,3);
Solve(9,5);
//Nと処理回数を引数として解を返す
function Solve($pN , $pSyoriCnt)
{
$JyunretuArr = DeriveJyunretuArr($pN);
$Answer=0;
foreach($JyunretuArr as $EachJyunretu){
$wkArr = $EachJyunretu;
for($I = 1 ; $I <= $pSyoriCnt ; $I++){
$wkArr = DeriveRevArr($wkArr);
if($wkArr[0] == 1){
if($I == $pSyoriCnt){
$Answer++;
//printf('解%dを発見' . PHP_EOL , $Answer);
//var_export($EachJyunretu);
}
else break;
}
}
}
printf('N=%d,処理回数=%dでは、%d通り' , $pN , $pSyoriCnt , $Answer);
echo PHP_EOL;
}
class JyoutaiDef
{
public $CurrArr;
}
//1からNまでの順列の配列を返す
function DeriveJyunretuArr($pN)
{
$WillReturn = array();
$Stk = new SplStack();
for($I = 2 ; $I <= $pN ; $I++){
$WillPush = new JyoutaiDef();
$WillPush->CurrArr = array($I);
$Stk->push($WillPush);
}
while($Stk->isEmpty() == false){
$Popped = $Stk->pop();
if(count($Popped->CurrArr) == $pN){
$WillReturn[] = $Popped->CurrArr;
continue;
}
for($I = 1 ; $I <= $pN ; $I++){
if(in_array($I,$Popped->CurrArr)) continue;
$WillPush = clone $Popped;
$WillPush->CurrArr[] = $I;
$Stk->push($WillPush);
}
}
return $WillReturn;
}
//先頭の値の分だけ、逆順にした配列を返す
function DeriveRevArr($pArr)
{
$WillReturn = $pArr;
$wkInd = $pArr[0]-1;
for($I = 0 ; $I <= $wkInd ; $I++){
$WillReturn[$I] = $pArr[$wkInd - $I];
}
return $WillReturn;
}
実行結果
N=4,処理回数=3では、4通り
N=9,処理回数=5では、28692通り
解説
深さ優先探索で順列を列挙してから、
シュミレーションしてます。