部活13
部活です。
テーマは変わらず。
19枚の同値類の組を、和が-1になるように選択しなおすについて。
長いのでさっさといきます。
****************************************************************************************
#define PANEL_SEL 20 // パネルの選択数
/* 19枚選択 */
typedef struct pan_sd {
int iEqclsAry[EQCLS_PT];
struct pan_sd *pstNext;
} stPanSd;
stPanSd *pstSdNow; // 現在探索中の同値類群
stPanSd *pstSdNext; // 次に探索する同値類群
int iSumSd; // 現在探索中の同値類群の和
・・・
pstSdNow = (stPanSd *)calloc(1, sizeof(stPanSd));
/* 最高点を求める */
for(iSel = 0, iSumSd = 0, iCnt1 = iEqclsMax;
(iCnt1 >= iEqclsMin) && (iSel < PANEL_SEL - 1); iCnt1--) {
/* 選択可能数分上から選ぶ */
pstSdNow->iEqclsAry[iCnt1] = MYMIN2(PANEL_SEL-1-iSel, iEqclsidx[iCnt1]);
iSumSd += pstSdNow->iEqclsAry[iCnt1] * iCnt1;
iSel += pstSdNow->iEqclsAry[iCnt1];
}
pstSdNow->pstNext = NULL;
・・・
stPanSd *pstSdLoop; // ループ用
stPanSd *pstSdDmy; // next用
stPanSd *pstSdNew; // アロケーション用
/* ③ */
for(pstSdLoop = pstSdNow, pstSdDmy = pstSdNext; pstSdLoop != NULL; ){
/* ①, ② */
for(iCnt1 = iEqclsMax; iCnt1 >= iEqclsMin; iCnt1--){
if( (pstSdLoop->iEqclsAry[iCnt1] > 0)
&& (iEqclsidx[iCnt1-1] - pstSdLoop->iEqclsAry[iCnt1-1] > 0) ) {
/* -1できる状態なら、-1する */
pstSdNew = (stPanSd *)calloc(1, sizeof(stPanSd));
*pstSdNew = *pstSdLoop; // Sのときの値をコピー
pstSdNew->iEqclsAry[iCnt1]--;
pstSdNew->iEqclsAry[iCnt1-1]++;
pstSdNew->pstNext = NULL; // 次はNULL
pstSdDmy->pstNext = pstSdNew; // 1こ前に繋げる
pstSdDmy = pstSdNew; // 次の保存先を1こずらす
}
}
}
****************************************************************************************
ブログに直書きするの疲れる。
実はこのアルゴリズムには、あることを考慮していないという欠陥があります。どっちかというと前回記事の欠陥ですね。分かった人は私の代わりに実装してください。ぜひ。
(コードのミスはわざとじゃないのであったら教えてください。)
それはまた次回。