26-04-2008, 18:09
|
|
|
חבר מתאריך: 26.04.08
הודעות: 2
|
|
הצעה לפתרון אחר
אפשר להסתמך קצת על המתמטיקה בשביל לחסוך כאן בזכרון:
נניח עבור הקלט n=5, k=3, בטור הראשון יהיו את המספרים 0 ו1, בעוד בתור השני יהיו את המספרים 0, 1 ו2.
בעצם, בכל טור (מלבד האחרון) המספר הכי נמוך יכול להיות 0, והמספר הכי גבוה יכול להיות שורש K של N.
עבור טור שלישי: שורש 3 של 5
עבור טור שני: שורש 2 של 5
וכך הלאה.
עכשיו, על כל טור לקיים גם את התנאי הבא: המספר שבו לא יכול להיות קטן מהמספר של הטור לפניו, אחרת יווצרו כפילויות.
ה"כיעור" בדוגמת הקוד שאני אביא נובע בגלל ההדפסה הדרושה, לכן רשמתי גם בpython וגם בC++ (דווקא C++ ולא C, כי יש שם את std::string)
הקוד בpython:
קוד:
from math import ceil
def f(n, k, prev = "", caller = 0):
if k == 1:
if n >= caller:
return n
return None
root = int(ceil(n**(1.0 / k))); # n**(1.0/k) = root K of N
for x in xrange(caller, root + 1):
l = str(prev) + str(x) + " "
res = f(n-x, k-1, l, x)
if res is not None:
print l + str(res)
return None
ובC++:
קוד:
#include <iostream>
#include <string>
#include <cmath>
using namespace std;
int f(int n, int k, string previous, int caller) {
if (k == 1) {
if (n >= caller) {
return n;
}
} else {
int root = (int)pow(n, 1.00 / k);
root = (int)ceil(root);
for (int i = caller;
i <= root + 1;
i++) {
string newPrev(previous);
char *buffer = new char[255];
sprintf(buffer, "%d ", i);
newPrev += buffer;
int result = f(n - i, k - 1, newPrev, i);
if (result != -1) { // Not failing result
cout << newPrev << result << endl;
}
}
}
return -1;
};
int main() {
int n, k;
cout << "Enter n: ";
cin >> n;
cout << "Enter k: ";
cin >> k;
f(n,k, "", 0);
return -1;
}
|