//-----------------------------------------------------------------------------
// 数値Nを重複しないN以下の数に分割するプログラム
//-----------------------------------------------------------------------------
// N -> Answer
// 3 -> Q=2 : 3, 2+1
// 4 -> Q=2 : 4, 3+1
// 5 -> Q=3 : 5, 4+1, 3+2
// 6 -> Q=4 : 6, 5+1, 4+2, 3+2+1
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <queue>
#include <stack>
#define LOG_ENABLE 0
#define MAXNUMBER 25
typedef struct {
int sum;
int start;
int hist[MAXNUMBER + 1];
} PartData;
void PartDataPrint(PartData* pd)
{
#if (LOG_ENABLE == 1)
int i;
for (i = 1; i <= pd->sum; i++) {
if (pd->hist[i]) {
printf("%d ", pd->hist[i]);
}
}
printf("\n");
#endif
}
//-----------------------------------------------------------------------------
// 総当たり実装
//-----------------------------------------------------------------------------
int brute_force(int N)
{
int num, i, val;
int count = 0;
for (num = 1; num < (1 << N); num++)
{
val = 0;
for (i = 0; i<MAXNUMBER; i++) {
if (num & (1 << i)) {
val += (i + 1);
}
}
if (val == N) {
#if (LOG_ENABLE == 1)
printf("[%2d] ",count);
for (i = 0; i<MAXNUMBER; i++) {
if (bitimg & (1 << i)) {
printf("%d ", i + 1);
}
}
printf("\n");
#endif
count++;
}
}
return count;
}
//-----------------------------------------------------------------------------
// 再起呼び出し実装
//-----------------------------------------------------------------------------
int recursive(int N, PartData* prev = NULL)
{
int n;
int num = 0;
PartData pd = { 0, 1 };
if (prev == NULL) { prev = &pd; }
for (n = prev->start; n <= N; n++)
{
PartData nd = *prev;
nd.sum += n;
nd.start = n + 1;
nd.hist[n] = n;
if (nd.sum > N) { return 0; }
if (nd.sum == N)
{
PartDataPrint(&nd);
num++;
return num;
}
else
{
num += recursive(N, &nd);
}
}
return num;
}
//-----------------------------------------------------------------------------
// スタック or キューを使った実装
//-----------------------------------------------------------------------------
int stack_or_que(int N, int isStack)
{
int i;
int num = 0;
std::stack<PartData> stk;
std::queue<PartData> que;
// 初期値登録
// 合計値 = 0
// ループ開始値 = 1
PartData s = { 0, 1 };
if (isStack) stk.push(s);
else que.push(s);
while ((isStack ? stk.size() : que.size()) > 0)
{
if (isStack) { s = stk.top(); stk.pop(); } // 値を取り出す
else { s = que.front(); que.pop(); } // 値を取り出す
// 目標値に到達していれば表示して次へ
if (s.sum == N)
{
PartDataPrint(&s);
num++;
continue;
}
// s を 1 要素分だけ探索
// "合計値 <= N" の条件に該当するものを登録
for (i = s.start; i <= N; i++)
{
PartData cp = s;
cp.sum += i;
cp.start = i + 1;
cp.hist[i] = i;
if (cp.sum > N)
{
break; // これ以上の探索は無駄なのでbreak
}
if (isStack) { stk.push(cp); }
else { que.push(cp); }
}
}
return num;
}
int main(int argc, char** argv)
{
int N = 0;
for (N = 1; N <= MAXNUMBER; N++)
{
int Q0 = brute_force(N);
int Q1 = stack_or_que(N, 1);
int Q2 = recursive(N);
if (Q0 != Q1 || Q0 != Q2) {
printf("[%2d] NG %d %d %d \n", N, Q0, Q1, Q2);
}
else {
printf("[%2d] OK %d %d %d \n", N, Q0, Q1, Q2);
}
}
return 0;
}
Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyDmlbDlgKRO44KS6YeN6KSH44GX44Gq44GETuS7peS4i+OBruaVsOOBq+WIhuWJsuOBmeOCi+ODl+ODreOCsOODqeODoAovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIE4gLT4gQW5zd2VyCi8vIDMgLT4gUT0yIDogMywgMisxCi8vIDQgLT4gUT0yIDogNCwgMysxCi8vIDUgLT4gUT0zIDogNSwgNCsxLCAzKzIKLy8gNiAtPiBRPTQgOiA2LCA1KzEsIDQrMiwgMysyKzEKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHF1ZXVlPgojaW5jbHVkZSA8c3RhY2s+CgojZGVmaW5lIExPR19FTkFCTEUgMAojZGVmaW5lIE1BWE5VTUJFUiAgMjUKCnR5cGVkZWYgc3RydWN0IHsKCWludCBzdW07CglpbnQgc3RhcnQ7CglpbnQgaGlzdFtNQVhOVU1CRVIgKyAxXTsKfSBQYXJ0RGF0YTsKCnZvaWQgUGFydERhdGFQcmludChQYXJ0RGF0YSogcGQpCnsKI2lmIChMT0dfRU5BQkxFID09IDEpCglpbnQgaTsKCWZvciAoaSA9IDE7IGkgPD0gcGQtPnN1bTsgaSsrKSB7CgkJaWYgKHBkLT5oaXN0W2ldKSB7CgkJCXByaW50ZigiJWQgIiwgcGQtPmhpc3RbaV0pOwoJCX0KCX0KCXByaW50ZigiXG4iKTsKI2VuZGlmCn0KCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8g57eP5b2T44Gf44KK5a6f6KOFCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KaW50IGJydXRlX2ZvcmNlKGludCBOKQp7CglpbnQgbnVtLCBpLCB2YWw7CglpbnQgY291bnQgPSAwOwoKCWZvciAobnVtID0gMTsgbnVtIDwgKDEgPDwgTik7IG51bSsrKQoJewoJCXZhbCA9IDA7CgkJZm9yIChpID0gMDsgaTxNQVhOVU1CRVI7IGkrKykgewoJCQlpZiAobnVtICYgKDEgPDwgaSkpIHsKCQkJCXZhbCArPSAoaSArIDEpOwoJCQl9CgkJfQoJCWlmICh2YWwgPT0gTikgewojaWYgKExPR19FTkFCTEUgPT0gMSkKCQkJcHJpbnRmKCJbJTJkXSAiLGNvdW50KTsKCQkJZm9yIChpID0gMDsgaTxNQVhOVU1CRVI7IGkrKykgewoJCQkJaWYgKGJpdGltZyAmICgxIDw8IGkpKSB7CgkJCQkJcHJpbnRmKCIlZCAiLCBpICsgMSk7CgkJCQl9CgkJCX0KCQkJcHJpbnRmKCJcbiIpOwojZW5kaWYKCQkJY291bnQrKzsKCQl9Cgl9CglyZXR1cm4gY291bnQ7Cn0KCgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIOWGjei1t+WRvOOBs+WHuuOBl+Wun+ijhQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmludCByZWN1cnNpdmUoaW50IE4sIFBhcnREYXRhKiBwcmV2ID0gTlVMTCkKewoJaW50IG47CglpbnQgbnVtID0gMDsKCVBhcnREYXRhIHBkID0geyAwLCAxIH07CgoJaWYgKHByZXYgPT0gTlVMTCkgeyBwcmV2ID0gJnBkOyB9CgoJZm9yIChuID0gcHJldi0+c3RhcnQ7IG4gPD0gTjsgbisrKQoJewoJCVBhcnREYXRhIG5kID0gKnByZXY7CgkJbmQuc3VtICs9IG47CgkJbmQuc3RhcnQgPSBuICsgMTsKCQluZC5oaXN0W25dID0gbjsKCgkJaWYgKG5kLnN1bSA+IE4pIHsgcmV0dXJuIDA7IH0KCQlpZiAobmQuc3VtID09IE4pCgkJewoJCQlQYXJ0RGF0YVByaW50KCZuZCk7CgkJCW51bSsrOwoJCQlyZXR1cm4gbnVtOwoJCX0KCQllbHNlCgkJewoJCQludW0gKz0gcmVjdXJzaXZlKE4sICZuZCk7CgkJfQoJfQoJcmV0dXJuIG51bTsKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyDjgrnjgr/jg4Pjgq8gb3Ig44Kt44Ol44O844KS5L2/44Gj44Gf5a6f6KOFCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KaW50IHN0YWNrX29yX3F1ZShpbnQgTiwgaW50IGlzU3RhY2spCnsKCWludCBpOwoJaW50IG51bSA9IDA7CglzdGQ6OnN0YWNrPFBhcnREYXRhPiBzdGs7CglzdGQ6OnF1ZXVlPFBhcnREYXRhPiBxdWU7CgoJLy8g5Yid5pyf5YCk55m76YyyCgkvLyAg5ZCI6KiI5YCkICAgICAgID0gMAoJLy8gIOODq+ODvOODl+mWi+Wni+WApCA9IDEKCVBhcnREYXRhIHMgPSB7IDAsIDEgfTsKCWlmIChpc1N0YWNrKQlzdGsucHVzaChzKTsKCWVsc2UgICAgICAgIHF1ZS5wdXNoKHMpOwoKCXdoaWxlICgoaXNTdGFjayA/IHN0ay5zaXplKCkgOiBxdWUuc2l6ZSgpKSA+IDApCgl7CgkJaWYgKGlzU3RhY2spIHsgcyA9IHN0ay50b3AoKTsgICBzdGsucG9wKCk7IH0gLy8g5YCk44KS5Y+W44KK5Ye644GZCgkJZWxzZSB7IHMgPSBxdWUuZnJvbnQoKTsgcXVlLnBvcCgpOyB9IC8vIOWApOOCkuWPluOCiuWHuuOBmQoKCQkvLyDnm67mqJnlgKTjgavliLDpgZTjgZfjgabjgYTjgozjgbDooajnpLrjgZfjgabmrKHjgbgKCQlpZiAocy5zdW0gPT0gTikKCQl7CgkJCVBhcnREYXRhUHJpbnQoJnMpOwoJCQludW0rKzsKCQkJY29udGludWU7CgkJfQoKCQkvLyBzIOOCkiAxIOimgee0oOWIhuOBoOOBkeaOoue0ogoJCS8vICLlkIjoqIjlgKQgPD0gTiIg44Gu5p2h5Lu244Gr6Kmy5b2T44GZ44KL44KC44Gu44KS55m76YyyCgkJZm9yIChpID0gcy5zdGFydDsgaSA8PSBOOyBpKyspCgkJewoJCQlQYXJ0RGF0YSBjcCA9IHM7CgkJCWNwLnN1bSArPSBpOwoJCQljcC5zdGFydCA9IGkgKyAxOwoJCQljcC5oaXN0W2ldID0gaTsKCgkJCWlmIChjcC5zdW0gPiBOKQoJCQl7CgkJCQlicmVhazsgLy8g44GT44KM5Lul5LiK44Gu5o6i57Si44Gv54Sh6aeE44Gq44Gu44GnYnJlYWsKCQkJfQoJCQlpZiAoaXNTdGFjaykgeyBzdGsucHVzaChjcCk7IH0KCQkJZWxzZSB7IHF1ZS5wdXNoKGNwKTsgfQoJCX0KCX0KCXJldHVybiBudW07Cn0KCmludCBtYWluKGludCBhcmdjLCBjaGFyKiogYXJndikKewoJaW50IE4gPSAwOwoKCWZvciAoTiA9IDE7IE4gPD0gTUFYTlVNQkVSOyBOKyspCgl7CgkJaW50IFEwID0gYnJ1dGVfZm9yY2UoTik7CgkJaW50IFExID0gc3RhY2tfb3JfcXVlKE4sIDEpOwoJCWludCBRMiA9IHJlY3Vyc2l2ZShOKTsKCgkJaWYgKFEwICE9IFExIHx8IFEwICE9IFEyKSB7CgkJCXByaW50ZigiWyUyZF0gTkcgJWQgJWQgJWQgXG4iLCBOLCBRMCwgUTEsIFEyKTsKCQl9CgkJZWxzZSB7CgkJCXByaW50ZigiWyUyZF0gT0sgJWQgJWQgJWQgXG4iLCBOLCBRMCwgUTEsIFEyKTsKCQl9Cgl9CglyZXR1cm4gMDsKfQoK