( uwaga, kod zadania )
Witam, treść zadania wszystko tłumaczy. Oczywiście nie chodzi o to że mi się nie chce a wy macie poszukiwać błąd w moim wykonaniu zadania... Już wiele razy sprawdzałem i wychodzą mi dobre wyniki z dobrą kolejnością. Jednak życie nauczyło mnie że jak coś się dzieje to Spoj mnie dobrze informuje a problemy są wyłącznie z mojej winy, więc się staram już tak nie oburzać ;) Wiem że jak więcej osób zerknie to może ktoś coś znajdzie...
treść zadania -> https://pl.spoj.com/problems/PTSUMY/
stronka z wynikami i kodem mojego programu -> https://ideone.com/9OUUPm
Plus jest taki że liczby wejściowe 'n' są 1>=n<=20, więc w linku są praktycznie odpowiedzi na każde możliwe dane wejściowe sędziego.
Ja osobiście błędu się w nich nie doszukałem...
Poniżej lekko wyjaśnię działanie mojego programu:
( przeczytaj funkcje returnCollection() przed wageElements() )
#include <iostream>
#include <vector>
using intc = std::vector<unsigned>;
using sets = std::vector<intc>;
///-----------------------------------------------------------------------------------
void wageElements(intc& acts, sets& res) {
for (int i = acts.size() - 1; i >= 1; --i) { //dla wszystkich elementów zbioru
while (!(acts[i-1] >= (acts[i]-1))) { // równoważymy ( od obecnego zbioru odejmujemy jeden i dodajemy jeden do tym co jest wcześniej ), robimy to do puki różnica między eleemntami będzie mniejsza lub równa jeden
acts[i] -= 1;
acts[i - 1] += 1;
if (i > 1) { //jeżeli kolejność jest leksykograficzna to dodajemy zbór do kolekcji zbiorów
if ((acts[i - 1] >= (acts[i] - 1)) && (acts[i - 2] >= (acts[i - 1] - 1)))
res.push_back(acts); //[*]
}
else //jeżeli pracujemy na elemencie drugim to zakładamy poprawną kolejnoość leksykograficzną
res.push_back(acts); //[*]
}
}
}
///------------------------------------------------------------------------------------
sets returnCollection(unsigned n) { //zwraca wszystkie możliwe zbiory
sets res; //wektor ze zbiorami
intc acts(n, 1); //zbiór na którym działamy i go po czasie zmieniamy ( aktualna przestrzeń pracy )
bool wasAdd{ false }; //by dwa razy czegoś nie dodać do wyjściowego wektora zbiorów, symbol [*]
while (acts[0]!=n) { //do puki w zbiorze nie będzie tylko jednej liczby równej 'n'
if(!wasAdd) res.push_back(acts);
int size = acts.size();
if (acts[size - 2] >= (acts[size - 1] - 1)) { //dodajemy dwie ostatnie liczby zbioru do siebie jeżeli są sobie równe lub różnica między nimi wynosi tylko jeden
int sum = acts[size - 1] + acts[size - 2];
acts.pop_back(); acts.pop_back();
acts.push_back(sum);
wasAdd = false; //jeszcze nie dodaliśmy tego zbioru
}
else {
wageElements(acts, res); //jeżeli różnica między ostatnimi liczbami zbioru wynosi więcej niż 1 to musimy dodać do kolekcji zbiorów wyjściowych postać zrównoważoną ( no bo mamy np dla liczby 4: 1,3 - da się to też zapisać jako 2,2 )
wasAdd = true; //ponieważ aktualny zbiór został już w tej funkcji dodany do kolekcji
}
}
res.push_back(acts); // dodajemy 'n'
return res;
}
///------------------------------------------------------------------------------------
int main() {
unsigned t;
std::cin >> t; //testy
for (int i = 0; i < t; ++i) {
unsigned n;
std::cin >> n; //liczba 1>=n<=20
auto r = returnCollection(n); // mamy w wektorze wszystkie zbiory liczb naturalnych w odpowiedniej kolejności
for (const auto& i : r) { //wypisywanie
for (const auto& j : i) {
std::cout << j << " ";
}
std::cout << "\n";
}
std::cout << "\n";
}
}
Trochę mi szkoda że sam sobie z problemem nie poradziłem, ale co zrobić :/
Z góry dziękuje za pomoc, chociaż są pytania tego typu które przez kilka lat nie uzyskały żadnej odpowiedzi :(