部活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こずらす

        }

    }

}

 ****************************************************************************************

 

ブログに直書きするの疲れる。

実はこのアルゴリズムには、あることを考慮していないという欠陥があります。どっちかというと前回記事の欠陥ですね。分かった人は私の代わりに実装してください。ぜひ。

(コードのミスはわざとじゃないのであったら教えてください。)

それはまた次回。