Problem z algorytmem

0

Dzień dobry !
Mam do napisania taki algorytm jak poniżej tylko mam z nim problem bo limit pamięci wynosi 64MB ,a mój program go przekracza. Więc mam pytanie gdzie tu najwięcej pamięci jest zabierane i jak to ograniczyć. Z góry dziękuje.

#include <iostream>
#include <string>
#include <cstdlib>
#include <vector>

using namespace std;

unsigned int ccsum(string s)
{
    unsigned int sum = 0;
    for(int i=0; i<s.length(); i++)
    {
        sum += atoi(new char(s[i]));
    }
    return sum;
}
unsigned int ccg(unsigned int n)
{
    return n + (ccsum(to_string(n)) * ccsum(to_string(n)));
}

int main()
{
    std::ios_base::sync_with_stdio(false);
    int x;
    cin >> x;
    long long n[x];
    for(int i=0; i<x; i++)
    {
        cin >> n[i];
    }

    for(int j=0; j<x; j++)
    {

        unsigned int nnx = 1;
        unsigned int nn = n[j];
        while(true)
        {
            if(nnx > nn)
            {
                cout << "NIE" << endl;
                break;
            }
            if(nnx == nn)
            {
                cout << "TAK" << endl;
                break;
            }
            nnx = ccg(nnx);
        }
    }

    return 0;
}



0

Co ten program ma robić, Opisz dokładnie.

0

Prawdopodobnie tutaj:

    cin >> x;
    long long n[x];

Chyba nie musisz przechowywać danych z poprzednich kroków aby obliczyć następny więc ta tablica wydaje się zbędna.
Bez znajomości treści zadania oraz zakresów wielkości danych wejściowych ciężko coś doradzić.

0
lion137 napisał(a):

Co ten program ma robić, Opisz dokładnie.

Reverse engineering z tak obłędnego fragmentu kodu nie ma szans.

 sum += atoi(new char(s[i]));

Tu masz po pierwsze wyciek pamięci, a po drugie i dla mnie ważniejsze ten fragment nie ma sensu. Luzując wszelkie "bezpieczniki" w głowie starałem się zrozumieć, co poeta miał na myśli, ale nie zgadłem

0
AnyKtokolwiek napisał(a):
lion137 napisał(a):

Co ten program ma robić, Opisz dokładnie.

Reverse engineering z tak obłędnego fragmentu kodu nie ma szans.

 sum += atoi(new char(s[i]));

Tu masz po pierwsze wyciek pamięci, a po drugie i dla mnie ważniejsze ten fragment nie ma sensu. Luzując wszelkie "bezpieczniki" w głowie starałem się zrozumieć, co poeta miał na myśli, ale nie zgadłem

Ta funkcja sumuje cyfry w liczbie np ccsum(2019) = 12
a ta linijka

 sum += atoi(new char(s[i]));

dodaje następną cyfre do sumy

0

ccsum(2019) = 2163 sumuje cyfry w liczbie? Skąd ten wynik?

0

To Wybrałeś chyba najtragiczniejszy sposób sumowania cyfr:) a tak?:

long sumDigits(long n) {
	long s = 0;
	while (n != 0) {
		s += n % 10;
		n /= 10; 
	}
	return s;
}
0
lion137 napisał(a):

To Wybrałeś chyba najtragiczniejszy sposób sumowania cyfr:) a tak?:

long sumDigits(long n) {
	long s = 0;
	while (n != 0) {
		s += n % 10;
		n /= 10; 
	}
	return s;
}

Dzięki wielkie zamienie funkcje i sprawdzę czy zużycie pamięci zmalało :)

0

Wszystko działa limit pamięci nie jest przekraczany , ale czas jest :(. Limit czasu na to zadanie wynosi 30s.
Podsyłam treść zadania :
Jest funkcja sum(n), która zwraca sumę cyfr liczby n. Jest też funkcja m(n). m(n) = n + sum(n)^2
Z tymi dwoma liczbami zaczynamy proces , który zaczyna się od n=1 i w następnym kroku obliczmy m(n) i przyjmujemy
za n wynik tej funkcji ( n = m(n) ).

Mamy za zadanie określić czy liczbę na wejściu da się uzyskać poprzez ten proces i wypisać TAK / NIE\

Przykłady :

Wejście:
4 - liczba "n" ( wielkość tablicy)
2
1
42
731

Wyjście:
TAK
TAK
TAK
NIE

0

Pokaz jaki Masz teraz kod i Podaj dokładna treść zadania z przykładami.

0

Co Ty tam tyle Pisałeś, to prosta funkcja jest(nie wiem jak wielkie to moga byc liczby, więc long może nie wystarczyć), a czy można szybciej? Złozoność będzie jakiś ułamek n razy stała, Sprawdź.:

std::string isReached(long n) {
	if (n == 1) return "TAK";
	long k = 1;
	long num = 0;
	while (k <= n) {
		num = sumDigits(k);
		k += num * num;
		if (k == n) return "TAK";
	}
	return "NIE";
}
int main(){
	std::cout << isReached(1) <<"\n"; // -> TAK
	std::cout << isReached(2) <<"\n"; // -> TAK
	std::cout << isReached(42) <<"\n"; // -> TAK
	std::cout << isReached(731) <<"\n"; // -> NIE
	std::cout << isReached(0) <<"\n"; // -> NIE
	return 0;
}

EDYCJA: Wydaje mi się, że już dla dużych "longów", to będzie działać długo...

0
lion137 napisał(a):

Co Ty tam tyle Pisałeś, to prosta funkcja jest(nie wiem jak wielkie to moga byc liczby, więc long może nie wystarczyć), a czy można szybciej? Złozoność będzie jakiś ułamek n razy stała,
Działa superrr test "obciążeniowy" na danych 5*10^9 kończy się w 1,5s.
Bardzo dziękuje za pomoc
Temat zamykam

0
helikson123 napisał(a):
AnyKtokolwiek napisał(a):
lion137 napisał(a):

Co ten program ma robić, Opisz dokładnie.

Reverse engineering z tak obłędnego fragmentu kodu nie ma szans.

 sum += atoi(new char(s[i]));

Tu masz po pierwsze wyciek pamięci, a po drugie i dla mnie ważniejsze ten fragment nie ma sensu. Luzując wszelkie "bezpieczniki" w głowie starałem się zrozumieć, co poeta miał na myśli, ale nie zgadłem

Ta funkcja sumuje cyfry w liczbie np ccsum(2019) = 12
a ta linijka

 sum += atoi(new char(s[i]));

dodaje następną cyfre do sumy

Dodaje ale "coś zaczynające się od cyfry", przetwarzasz string jeden Pan Bóg wie jakiej długości (specyfikacja atoi).
Masz jakąś obronę co do new char?

1 użytkowników online, w tym zalogowanych: 0, gości: 1