SPOJ "Niedokładne kodowanie"

0

Witam , mam problem z zadaniem do SPOJA (nie mogę napisać na forum SPOJA bo jest problem jakiś) kod działa i wypisuje poprawne dane dla przykładów ale SPOJ nie chcę go zaakceptować szukałem w google i nic nie znalazłem , ktoś pomoże?

link do zadania http://pl.spoj.com/problems/ETI06E1/
Sorki za kod :D

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

using namespace std;

int maxx = 8;
int x = 0;
int za , od , countt;
bool brkk = false ;
int buf[10001];
char ciag[10001];
//-------------------------------------------------------------------
void nastepne_rozwiazanie()
{
	buf[0]++;
	for(int i = 0; i < za; i++){
		if(buf[i] == maxx){
			buf[i+1]++;
			buf[i] = 1;
		}
	}
}
//-------------------------------------------------------------------
void wypisz_rozwiazanie()
{
	x = 0;
	for(int i = 0; i < za; i++){ 
		int it = buf[x];
		string tmp = "";
		
		for(int j = 0; j < it; j++)
			tmp += ciag[i+j];
		
		int xx = atoi(tmp.c_str());

		for(int j = 0; j < xx; j++)
			cout << ciag[i+it];
		i = i + it;
		x++;
	}
}
//-------------------------------------------------------------------
bool sprawdz_rozwiazanie()
{
	countt = 0;
	x = 0;
	for(int i = 0; i < za; i++){
		
		int it = buf[x];
		string tmp = "" ;

		for(int j = 0; j < it; j++){
			tmp += ciag[i+j] ;
			}
		if(ciag[i] == '0'){
			countt = 0;
			brkk = true;
			return true;
		}
		if(brkk){
			brkk = false;
		  break;
		}
		countt += atoi(tmp.c_str());
		i = i + it;
		x++;
	}
	if(countt == od)
		return false;
	return true;
}
//-------------------------------------------------------------------
void wczytaj_dane(){
	for(int i = 0; i < 10001; i++){
		buf[i] = 1;
		ciag[i] = '0';
	}
	cin >> za >> od;
	cin >> ciag;	
}
//-------------------------------------------------------------------
int main(){
   
	wczytaj_dane();

	while(sprawdz_rozwiazanie()){
		nastepne_rozwiazanie();
	}
	wypisz_rozwiazanie();
}
0

wypisuje poprawne dane dla przykładów ale SPOJ nie chcę go zaakceptować

Ale jaki jest błąd? Zła odpowiedź? Przekroczenie czasu? Przekroczenie pamięci?
Poza tym kod jest na tyle zagmatwany że założe się że ma blędy ;] To całe zadanie można napisać w 15-20 linijkach, tylko trzeba myślec... Poza tym naucz się nazywać zmienne tak żebyś wiedział co oznaczają.

0

Noc + parę piwek = obfuskacja level expert :D

Jest zagmatwany ale działa niby , sędzia daje "błędna odpowiedz"

Dla danych przykładowych działa

Jak byście mogli mnie naprowadzić jakoś był bym wdzięczny bo nie mam pomysłu , nie jestem tak dobry jak wy

0

Znaczy że kod nie jest poprawny. To ze działa dla przykładowych danych nie znaczy absolutnie nic ;]
Niestety takiego spaghetti nikt ci nie pomoże debugować. Skasuj. Napisz od nowa.

0

A teraz ktoś pomoże? ^^

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

using namespace std;

int x = 0;
int za , od , count;
bool brk = false;
int buf[10001];
char ciag[10001];

void wypisz()
{
	x = 0;
	for(int i = 0; i < za; i++){ 
		int it = buf[x];
		string tmp = "";
		
		for(int j = 0; j < it; j++)
			tmp += ciag[i+j];
		
		int xx = atoi(tmp.c_str());

		for(int j = 0; j < xx; j++)
			cout << ciag[i+it];
		i = i + it;
		x++;
	}
}

void dodaj_do_count()
{
	count = 0;
	x = 0;
	for(int i = 0; i < za; i++){
		
		int it = buf[x];
		string tmp = "" ;

		for(int j = 0; j < it; j++){
			tmp += ciag[i+j] ;
			}
		if(ciag[i] == '0'){
			count = 0;
			brk = true;
			break;
		}
		
		if(brk){
			brk  = false;
			break;
		}
		count += atoi(tmp.c_str());
		i = i + it;
		x++;
	}
}

int main(){

	int max = 7;
	for(int i = 0; i < 10001; i++){
		buf[i] = 1;
		ciag[i] = '0';
	}

	cin >> za >> od;
	cin >> ciag;

	while(true){

		dodaj_do_count();
		if(count == od){
			wypisz();
			break;
		}
		else{
			buf[0]++;
			for(int i = 0; i < za; i++){
				if(buf[i] == max){
					buf[i+1]++;
					buf[i] = 1;
				}
			}
		}
	}
}

1

Pokaż ten kod swojej mamie albo siostrze i spytaj czy wiedzą co on robi. Nie? To znaczy że jest nieczytelny. Czytelny kod miałby strukturę na przykład taką:

wczytajDane();
while(istniejąNieprzetestowaneDekodowania()){
  wyliczKolejneDekodowanie();
  if(noweDekodowaneMniejszeOdAktualnegoMinumum()){
      zapamiętajNoweDekodowanie();
  }
}
wypiszZnalezioneRozwiązanie();
0

Oto test case, dla którego twój kod nie podaje prawidłowego wyniku (przegapiłeś warunek brzegowy: liczba nie zaczyna się od zera):

14 27
10113221011322

http://melpon.org/wandbox/permlink/6AnsVty7AAiHFRYq
http://melpon.org/wandbox/permlink/bPTMMhTKAFCzrSl1 (nieźle pod clang to się nie kompiluje :P)
Prawidłowy wynik to: 111111111132203333333333322

1

W takich wypadkach najlepiej stworzyć sobie zestaw danych testowych.
Jeśli brak pomysłów to można zawsze liczyć na ślepy los generując losowo dane testowe i sprawdzać, czy wynik spełnia założenia zadania (akurat dla tego zadania takie podejście jest dość łatwe do zrobienia):

std::string encode(const std::string &s) {
    std::stringstream result;
    std::string::const_iterator i = s.begin();
    while(i!=s.end()) {
        char ch = *i++;
        int rep = 1;
        while(i!=s.end() && ch==*i) {
            ++rep;
            ++i;
        }
        result << rep << ch;
    }
    return result.str();
}

std::string randomData(int maxRep, int n) {
    std::stringstream result;
    int totalLen = 0;
    char lastChar = '0';
    for (int i=0; i<n; ++i) {
        char ch = '0'+rand()%9;
        if (ch>=lastChar)
            ++ch;
        int rep = 1+rand()%maxRep;
        totalLen+=rep;
        if(totalLen>DecodedMaxLen)
            break;
        result << std::string(rep,ch);
        lastChar = ch;
    }
    return result.str();
}

int main() {
// taki trik by testować u siebie (projekt ma zdefiniowany symbol RANDOM_TEST)
// a potem bezpiecznie ten sam kod wysyłać do SPOJ-a:
#ifdef RANDOM_TEST
    for (int i=0; i<5000; ++i) {
        std::string test = randomData(15,6);
        std::string encoded = encode(test);
        std::string result = tryDecode(encoded.data(), encoded.length(), test.length());
        if (result!=test) {
            if (result.length()!=test.length()) {
                std::cout << "Lenght fail:\n expected: " << test
                          << "\n     have: " << result
                          << "\ntest data: \n"
                          << encoded.length()<< " " << test.length()<<'\n'
                          << encoded << '\n' <<  std::endl;
            } else if (result>test) {
                std::cout << "Lex fail:\n expected: " << test
                          << "\n     have: " << result
                          << "\ntest data: \n"
                          << encoded.length()<< " " << test.length()<<'\n'
                          << encoded << '\n' <<  std::endl;
            } else if (result[0]=='0') {
                std::cout << "Zerro start fail:\n expected: " << test
                          << "\n     have: " << result
                          << "\ntest data: \n"
                          << encoded.length()<< " " << test.length()<<'\n'
                          << encoded << '\n' <<  std::endl;
            } else if (encode(result)!=encoded) {
                std::cout << "Doesn't encode in same maner:\n expected: " << test
                          << "\n     have: " << result
                          << "\ntest data: \n"
                          << encoded.length()<< " " << test.length()<<'\n'
                          << encoded << '\n' <<  std::endl;
            }
        }
    }
#else
    int encLen, decLen;
    std::string encoded;
    while (std::getline(std::cin >> encLen >> decLen >> std::ws, encoded)) {
        std::cout << tryDecode(encoded.data(), encLen, decLen) << std::endl;
    }
#endif
    return 0;
}

Gdzie tryDecode to moja próba rozwiązania zadanie (też nieudana).
W ten sposób wyłowiłem kilka przypadków kiedy mój kod zwraca wartości nie spełniające założeń zadania. Spróbuj tego podejścia, powinno pomóc.

Offtopic: Tu widać też, czemu lepiej pisać kod logicznymi małymi funkcjami. Łatwiej się go testuje.

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