Optymylizacja kodu programu

0

Witam czy moglibyście pomóc mi w optymalizacji tego kodu

 
#include <iostream>
#include <conio.h>
#include <ctime>

using namespace std;

int tab[100000];
int tab1[100000];
int wyn[100000];
int wyn2[100000];
int wyn1[100000];
	
int main(int argc, char argv[])
{   

	int k,a,m,u,n,bol,l;
	time_t start,finish;
	start = time(NULL);



    
	a=1;
	k=1;
	n=100000;
        m=0;
	l=0;
	u=0;
       //cin >> n;
	
	while(n)
	{
		n--;
		

		//cin >> a >> k;
		tab[m]=a;
		tab1[m]=k;
                m++;
	}
	
			for(int i=0;i<m;i++)
			{
				bol=0;
				for(int e=0;e<m;e++)
				{
				   if(wyn2[e]==tab[i])
				   {
					   bol=1;
					   e=m;
				   }
				}
				if(bol==0)
				{
				    wyn2[l]=tab[i];
				    bol=0;
				    l++;
						
				}
			}

			for(int i=0;i<m;i++)
			{
				bol=0;
			    for(int e=0;e<m;e++)
				{  
				    if(tab[i] == tab[e]) 
						wyn1[i]+=tab1[e]; 
				   
						if(wyn[e]==tab[i] && bol==0) 
							bol=1;
				
                }
				if(bol==0)
				{
					wyn[i]=tab[i]; 
						
				}
						
			}
	for(int i=0;i<l;i++)
	{
	    if(!wyn2[i]==0)
		{
		    u++;
		}

	}

	printf("%u \n",u);
	for(int i=0;i<m;i++)
	{
		if(!wyn[i] == 0)
		{
			printf("%u %u \n",wyn[i],wyn1[i]);
		}
	}
	finish = time(NULL);
	cout << "Czas: " << (finish-start);
	getch();
	return 0;
}

Muszę się zmieścić w przedziale czasowym 1-10s a mam 32s ;/ myślę nad tym od półtora dnia i nie wiem jak to zoptymalizować do tych 10s AnyWay na początku było 70s tak że i tak sporo zoptymalizowałem by nie było że nic nie robiłem ^^
Tu link do zadania ;) By wiadomo było co robi program https://pl.spoj.pl/problems/OIG1_SKL/ wszystkie dane wyjściowe z programu są poprawne;)

0

Użyj vector i map. Oto gotowiec, przepraszam, że zepsułem przyjemność rozwiązywania zadania <haha>:

#include <map>
#include <cstdio>
#include <vector>

int main(int argc, char** argv) {

    int _, iloscWierszy;
    _ = scanf("%d", &iloscWierszy);

    std::map<int, int> ilosci;
    std::vector<int> produkty;

    for (int wiersz = 0; wiersz < iloscWierszy; wiersz++) {
        int produkt, ilosc;
        _ = scanf("%d %d", &produkt, &ilosc);
        if (ilosci.count(produkt) > 0) {
            ilosci[produkt] += ilosc;
        } else {
            produkty.push_back(produkt);
            ilosci[produkt] = ilosc;
        }
    }

    printf("%zu\n", produkty.size());
    for (std::vector<int>::const_iterator produkt = produkty.begin(); produkt != produkty.end(); ++produkt) {
        printf("%d %d\n", *produkt, ilosci[*produkt]);
    }
}

Edit:
Niestety ten program nie mieści się w limicie. Jest ok 13 s, a limit wynosi 10 s. Generalnie sprawę załatwiłoby zamienienie mapy na hash_mapę, ale nie wiem na razie jak to zapisać. Niby nagłówek <hash_map> jest, ale jak tego użyć? :P

Zrobiłem własną hash mapę:

#include <cstdio>
#include <cstring>

struct Produkt {
    int numer;
    int ilosc;
};

const int MaxProduktow = 1024 * 1024;
Produkt mapa[MaxProduktow];
Produkt* produkty[MaxProduktow];

int main(int argc, char** argv) {

    int _, iloscWierszy;
    _ = scanf("%d", &iloscWierszy);

    int produktow = 0;

    memset(mapa, -1, sizeof (mapa));

    for (int wiersz = 0; wiersz < iloscWierszy; wiersz++) {
        int numer, ilosc;
        _ = scanf("%d %d", &numer, &ilosc);

        int hash = (numer * 23452457) & (MaxProduktow - 1);

        while ((mapa[hash].numer != numer) && (mapa[hash].numer != -1)) {
            hash = (hash + 7) & (MaxProduktow - 1);
        }

        if (mapa[hash].numer == -1) {
            mapa[hash].numer = numer;
            mapa[hash].ilosc = ilosc;
            produkty[produktow] = &mapa[hash];
            produktow++;
        } else {
            mapa[hash].ilosc += ilosc;
        }
    }

    printf("%d\n", produktow);
    for (int produkt = 0; produkt < produktow; produkt++) {
        printf("%d %d\n", produkty[produkt]->numer, produkty[produkt]->ilosc);
    }
}

Teraz czas jest lepszy.

Edit:
Tak jak sądziłem, samodzielne parsowanie może przyspieszyć znacznie program. Z tym programem wylądowałem na 5 miejscu w zestawieniu najlepszych:

#include <cstdio>
#include <cstring>

struct Produkt {
    int numer;
    int ilosc;
};

const int MaxProduktow = 1024 * 1024;
Produkt mapa[MaxProduktow];
Produkt* produkty[MaxProduktow];

char buforWejscia[15 * 1000 * 1000 + 20];

int main(int argc, char** argv) {

    int _, iloscWierszy;
    _ = scanf("%d", &iloscWierszy);

    int produktow = 0;

    memset(mapa, -1, sizeof (mapa));

    int wczytanychBajtow = fread(buforWejscia, 1, sizeof (buforWejscia) - 1, stdin);
    buforWejscia[wczytanychBajtow] = 0;
    int bajt = 0;
    for (int wiersz = 0; wiersz < iloscWierszy; wiersz++) {
        bajt += 1;
        int numer = 0;
        while (buforWejscia[bajt] >= '0') {
            numer *= 10;
            numer += buforWejscia[bajt] - '0';
            bajt++;
        }
        bajt += 1;
        int ilosc = 0;
        while (buforWejscia[bajt] >= '0') {
            ilosc *= 10;
            ilosc += buforWejscia[bajt] - '0';
            bajt++;
        }

        int hash = ((((((2166136261 * 16777619) ^ (numer & 0xff)) * 16777619) ^ ((numer >> 8) & 0xff)) * 16777619) ^
                (numer >> 16)) & (MaxProduktow - 1);

        while ((mapa[hash].numer ^ numer) > 0) {
            hash = (hash + 1) & (MaxProduktow - 1);
        }

        if (mapa[hash].numer == -1) {
            mapa[hash].numer = numer;
            mapa[hash].ilosc = ilosc;
            produkty[produktow] = &mapa[hash];
            produktow++;
        } else {
            mapa[hash].ilosc += ilosc;
        }
    }

    printf("%d\n", produktow);
    for (int produkt = 0; produkt < produktow; produkt++) {
        printf("%d %d\n", produkty[produkt]->numer, produkty[produkt]->ilosc);
    }
}

Pewnie sporo da się jeszcze przyspieszyć wczytywanie, bo najlepsi mają kilkadziesiąt procent szybsze programy.

0

Nie kumam tego jak można kombinować jakieś hashe kiedy to się załatwia prostym sortowaniem. Proste jak drut !!

#include <iostream>
#include <algorithm>
using namespace std;

struct Lista { unsigned nr,id,count; };

bool byid(const Lista &a,const Lista &b) { return a.id<b.id; }
bool bynr(const Lista &a,const Lista &b) { return a.nr<b.nr; }

int main()
  {
   unsigned n;
   cin>>n;
   Lista *L=new Lista[n];
   for(unsigned i=0;i<n;++i)
     {
      L[i].nr=i;
      cin>>L[i].id>>L[i].count;
     }
   sort(L,L+n,byid);
   unsigned id=0,p=0;
   for(unsigned i=0;i<n;++i)
     {
      if(id!=L[i].id) id=L[p=i].id;
      else
        {
         L[p].count+=L[i].count;
         L[i].nr=n;
        }
     }
   sort(L,L+n,bynr);
   p=0;
   for(unsigned i=0;(i<n)&&(L[i].nr<n);++i) ++p;
   cout<<p<<endl;
   for(unsigned i=0;i<p;++i) cout<<L[i].id<<' '<<L[i].count<<endl;
   delete[] L;
   //cin.sync(); cin.get();
   return 0;
  }

EDIT:
Wersja na wskaźnikach:

#include <iostream>
#include <algorithm>
using namespace std;

struct Lista { unsigned nr,id,count; };

bool byid(const Lista &a,const Lista &b) { return a.id<b.id; }
bool bynr(const Lista &a,const Lista &b) { return a.nr<b.nr; }

int main()
  {
   unsigned N;
   cin>>N;
   Lista *L=new Lista[N],*E=L+N,*w=L,*v=0;
   for(unsigned i=0;i<N;++i,++w)
     {
      w->nr=i;
      cin>>w->id>>w->count;
     }
   sort(L,E,byid);
   unsigned id=0,n=0;
   for(w=L;w<E;++w)
     {
      if(id!=w->id)
        {
         id=(v=w)->id;
         ++n;
        }
      else
        {
         v->count+=w->count;
         w->nr=N;
        }
     }
   sort(L,E,bynr);
   cout<<n<<endl;
   for(w=L,E=L+n;w<E;++w) cout<<w->id<<' '<<w->count<<endl;
   delete[] L;
   cin.sync(); cin.get();
   return 0;
  }
0

A ja nie kumam jak można robić sortowania w czasie O(n lg n), zamiast użyć tablicy hashującej i zamknąć się w czasie oczekiwanym O(n) :)
Moja pierwsza wersja ma złożoność pesymistyczną O(n lg n), ale za dużą stałą.

Tak czy siak kody Dragona nie działają na SPOJu. Zrób sobie konto na SPOJu i wrzuć swoje rozwiązania. Moja ostateczna wersja zajmuje 29M, Dragona 2.6M. Jeden mój submit zżerał 186M i też przeszedł :P (ten submit był chyba 6 najszybszy, lekko wolniejszy niż ostateczny).

Edit:
Wersja Dragona nie wiadomo ile zajmuje RAMu. 2.6M jest pokazywane przy wszystkich programach w C++, które nie przechodzą.

0

Ok dzięki za podpowiedź. Jeszcze jedno pytanie czy dobrze rozumiem ten zapis :

Lista *L=new Lista[N],*E=L+N,*w=L,*v=0; 

Czyli Lista[N] to tablica? a E to wskaźnik na koniec tablicy , w to wskaźnik na L a v to wskaźnik na w ? Dobrze rozumiem

0

@ _13th_Dragon ciekawa koncepcja, ale wyszukiwanie w hashmapie optymistycznie jest w O(1) a nie O(logn) o ile funkcja hashująca jest porządna. W ogóle nie wiem skad pomysł ze mogłoby być tam log(n), skoro hashtable ma optymistycznie O(1) a pesymistycznie O(n). Może ci się pomyliło z jakimś treemap? To że akurat <map> z STL jest mapą tree-map a nie hash-map nie znaczy że każda taka jest.

2

Nie widać, że zrobiłem wersję z własną hashmapą? Złożoność oczekiwana mojej najlepszej wersji to O(n). Hashmapy z STLa nie wiem jak użyć :P

0

Jak na razie jestem najlepszy :P Czas 1.46 s, pamięć 43M. Mój program:

#include <cstdio>
#include <cstring>
#include <cstdlib>

struct Produkt {
    int numer;
    int ilosc;
};

char zbitkiCyfr[1000][4][4]; // 0 - normalne + spacja, 1 - normalne + enter, 2 - stała szerokość + spacja, 3 ....
char dlugosciZbitkow[1000][4];

int main(int argc, char** argv) {

    int zbitka = 0;
    for (int i = 0; i < 10; i++) {
        if (i == 0) {
            for (int j = 0; j < 10; j++) {
                if (j == 0) {
                    for (int k = 0; k < 10; k++, zbitka++) {
                        zbitkiCyfr[zbitka][0][0] = '0' + k;
                        zbitkiCyfr[zbitka][0][1] = ' ';
                        dlugosciZbitkow[zbitka][0] = 2;
                        zbitkiCyfr[zbitka][1][0] = '0' + k;
                        zbitkiCyfr[zbitka][1][1] = 10;
                        dlugosciZbitkow[zbitka][1] = 2;
                        zbitkiCyfr[zbitka][2][0] = '0';
                        zbitkiCyfr[zbitka][2][1] = '0';
                        zbitkiCyfr[zbitka][2][2] = '0' + k;
                        zbitkiCyfr[zbitka][2][3] = ' ';
                        dlugosciZbitkow[zbitka][2] = 4;
                        zbitkiCyfr[zbitka][3][0] = '0';
                        zbitkiCyfr[zbitka][3][1] = '0';
                        zbitkiCyfr[zbitka][3][2] = '0' + k;
                        zbitkiCyfr[zbitka][3][3] = 10;
                        dlugosciZbitkow[zbitka][3] = 4;
                    }
                } else {
                    for (int k = 0; k < 10; k++, zbitka++) {
                        zbitkiCyfr[zbitka][0][0] = '0' + j;
                        zbitkiCyfr[zbitka][0][1] = '0' + k;
                        zbitkiCyfr[zbitka][0][2] = ' ';
                        dlugosciZbitkow[zbitka][0] = 3;
                        zbitkiCyfr[zbitka][1][0] = '0' + j;
                        zbitkiCyfr[zbitka][1][1] = '0' + k;
                        zbitkiCyfr[zbitka][1][2] = 10;
                        dlugosciZbitkow[zbitka][1] = 3;
                        zbitkiCyfr[zbitka][2][0] = '0';
                        zbitkiCyfr[zbitka][2][1] = '0' + j;
                        zbitkiCyfr[zbitka][2][2] = '0' + k;
                        zbitkiCyfr[zbitka][2][3] = ' ';
                        dlugosciZbitkow[zbitka][2] = 4;
                        zbitkiCyfr[zbitka][3][0] = '0';
                        zbitkiCyfr[zbitka][3][1] = '0' + j;
                        zbitkiCyfr[zbitka][3][2] = '0' + k;
                        zbitkiCyfr[zbitka][3][3] = 10;
                        dlugosciZbitkow[zbitka][3] = 4;
                    }
                }
            }
        } else {
            for (int j = 0; j < 10; j++) {
                for (int k = 0; k < 10; k++, zbitka++) {
                    zbitkiCyfr[zbitka][0][0] = '0' + i;
                    zbitkiCyfr[zbitka][0][1] = '0' + j;
                    zbitkiCyfr[zbitka][0][2] = '0' + k;
                    zbitkiCyfr[zbitka][0][3] = ' ';
                    dlugosciZbitkow[zbitka][0] = 4;
                    zbitkiCyfr[zbitka][1][0] = '0' + i;
                    zbitkiCyfr[zbitka][1][1] = '0' + j;
                    zbitkiCyfr[zbitka][1][2] = '0' + k;
                    zbitkiCyfr[zbitka][1][3] = 10;
                    dlugosciZbitkow[zbitka][1] = 4;
                    zbitkiCyfr[zbitka][2][0] = '0' + i;
                    zbitkiCyfr[zbitka][2][1] = '0' + j;
                    zbitkiCyfr[zbitka][2][2] = '0' + k;
                    zbitkiCyfr[zbitka][2][3] = ' ';
                    dlugosciZbitkow[zbitka][2] = 4;
                    zbitkiCyfr[zbitka][3][0] = '0' + i;
                    zbitkiCyfr[zbitka][3][1] = '0' + j;
                    zbitkiCyfr[zbitka][3][2] = '0' + k;
                    zbitkiCyfr[zbitka][3][3] = 10;
                    dlugosciZbitkow[zbitka][3] = 4;
                }
            }
        }
    }

    int _, iloscWierszy;
    _ = scanf("%d", &iloscWierszy);

    int MaxProduktow = 1024 * 1024;
    while (MaxProduktow > 5 * iloscWierszy) {
        MaxProduktow >>= 1;
    }
    int MaxProduktowMaska = MaxProduktow - 1;
    Produkt mapa[MaxProduktow];
    Produkt * produkty[MaxProduktow];

    memset(mapa, -1, sizeof (mapa));

    int produktow = 0;

    char * buforWejscia = new char[15 * iloscWierszy + 20];

    int wczytanychBajtow = fread(buforWejscia, 1, 15 * iloscWierszy - 1, stdin);
    buforWejscia[wczytanychBajtow] = 0;
    int bajt = 0;
    for (int wiersz = 0; wiersz < iloscWierszy; wiersz++) {
        bajt += 1;
        int numer = 0;
        while (buforWejscia[bajt] >= '0') {
            numer *= 10;
            numer += buforWejscia[bajt] - '0';
            bajt++;
        }
        bajt += 1;
        int ilosc = 0;
        while (buforWejscia[bajt] >= '0') {
            ilosc *= 10;
            ilosc += buforWejscia[bajt] - '0';
            bajt++;
        }

        int hash = ((((((2166136261 * 16777619) ^ (numer & 0xff)) * 16777619) ^ ((numer >> 8) & 0xff)) * 16777619) ^
                (numer >> 16)) & MaxProduktowMaska;

        while ((mapa[hash].numer ^ numer) > 0) {
            hash = (hash + 1) & MaxProduktowMaska;
        }

        if (mapa[hash].numer == -1) {
            mapa[hash].numer = numer;
            mapa[hash].ilosc = ilosc;
            produkty[produktow] = &mapa[hash];
            produktow++;
        } else {
            mapa[hash].ilosc += ilosc;
        }
    }

    printf("%d\n", produktow);
    char *buforWyjscia = new char[22 * produktow + 20];
    int wypisanychBajtow = 0;
    for (int produkt = 0; produkt < produktow; produkt++) {
        int numer = produkty[produkt]->numer;
        int ilosc = produkty[produkt]->ilosc;

        int miliardy;

        miliardy = numer / 1000000000;
        if (miliardy == 0) {
            int miliony = numer / 1000000;
            if (miliony == 0) {
                int tysiace = numer / 1000;
                if (tysiace == 0) {
                    int koncowka = numer % 1000;
                    int32_t *ptr = (int32_t *) & buforWyjscia[wypisanychBajtow];
                    *ptr = *(int32_t *) zbitkiCyfr[koncowka][0];
                    wypisanychBajtow += dlugosciZbitkow[koncowka][0];
                } else {
                    int koncowka = numer % 1000;
                    int32_t *ptr = (int32_t *) & buforWyjscia[wypisanychBajtow];
                    *ptr = *(int32_t *) zbitkiCyfr[tysiace][0];
                    wypisanychBajtow += dlugosciZbitkow[tysiace][0] - 1;
                    ptr = (int32_t *) & buforWyjscia[wypisanychBajtow];
                    *ptr = *(int32_t *) zbitkiCyfr[koncowka][2];
                    wypisanychBajtow += dlugosciZbitkow[koncowka][2];
                }
            } else {
                int tysiace = (numer - miliony * 1000000) / 1000;
                int koncowka = numer % 1000;
                int32_t *ptr = (int32_t *) & buforWyjscia[wypisanychBajtow];
                *ptr = *(int32_t *) zbitkiCyfr[miliony][0];
                wypisanychBajtow += dlugosciZbitkow[miliony][0] - 1;
                ptr = (int32_t *) & buforWyjscia[wypisanychBajtow];
                *ptr = *(int32_t *) zbitkiCyfr[tysiace][2];
                wypisanychBajtow += 3;
                ptr = (int32_t *) & buforWyjscia[wypisanychBajtow];
                *ptr = *(int32_t *) zbitkiCyfr[koncowka][2];
                wypisanychBajtow += 4;
            }
        } else {
            buforWyjscia[wypisanychBajtow] = '1';
            wypisanychBajtow++;
            buforWyjscia[wypisanychBajtow] = '0';
            wypisanychBajtow++;
            buforWyjscia[wypisanychBajtow] = '0';
            wypisanychBajtow++;
            buforWyjscia[wypisanychBajtow] = '0';
            wypisanychBajtow++;
            buforWyjscia[wypisanychBajtow] = '0';
            wypisanychBajtow++;
            buforWyjscia[wypisanychBajtow] = '0';
            wypisanychBajtow++;
            buforWyjscia[wypisanychBajtow] = '0';
            wypisanychBajtow++;
            buforWyjscia[wypisanychBajtow] = '0';
            wypisanychBajtow++;
            buforWyjscia[wypisanychBajtow] = '0';
            wypisanychBajtow++;
            buforWyjscia[wypisanychBajtow] = '0';
            wypisanychBajtow++;
            buforWyjscia[wypisanychBajtow] = ' ';
            wypisanychBajtow++;
        }

        miliardy = ilosc / 1000000000;
        if (miliardy == 0) {
            int miliony = ilosc / 1000000;
            if (miliony == 0) {
                int tysiace = ilosc / 1000;
                if (tysiace == 0) {
                    int koncowka = ilosc % 1000;
                    int32_t *ptr = (int32_t *) & buforWyjscia[wypisanychBajtow];
                    *ptr = *(int32_t *) zbitkiCyfr[koncowka][1];
                    wypisanychBajtow += dlugosciZbitkow[koncowka][1];
                } else {
                    int koncowka = ilosc % 1000;
                    int32_t *ptr = (int32_t *) & buforWyjscia[wypisanychBajtow];
                    *ptr = *(int32_t *) zbitkiCyfr[tysiace][1];
                    wypisanychBajtow += dlugosciZbitkow[tysiace][1] - 1;
                    ptr = (int32_t *) & buforWyjscia[wypisanychBajtow];
                    *ptr = *(int32_t *) zbitkiCyfr[koncowka][3];
                    wypisanychBajtow += dlugosciZbitkow[koncowka][3];
                }
            } else {
                int tysiace = (ilosc - miliony * 1000000) / 1000;
                int koncowka = ilosc % 1000;
                int32_t *ptr = (int32_t *) & buforWyjscia[wypisanychBajtow];
                *ptr = *(int32_t *) zbitkiCyfr[miliony][1];
                wypisanychBajtow += dlugosciZbitkow[miliony][1] - 1;
                ptr = (int32_t *) & buforWyjscia[wypisanychBajtow];
                *ptr = *(int32_t *) zbitkiCyfr[tysiace][3];
                wypisanychBajtow += 3;
                ptr = (int32_t *) & buforWyjscia[wypisanychBajtow];
                *ptr = *(int32_t *) zbitkiCyfr[koncowka][3];
                wypisanychBajtow += 4;
            }
        } else {
            buforWyjscia[wypisanychBajtow] = '0' + miliardy;
            wypisanychBajtow++;
            int miliony = (ilosc % 1000000000) / 1000000;
            int tysiace = (ilosc % 1000000) / 1000;
            int koncowka = ilosc % 1000;
            int32_t *ptr = (int32_t *) & buforWyjscia[wypisanychBajtow];
            *ptr = *(int32_t *) zbitkiCyfr[miliony][1];
            wypisanychBajtow += dlugosciZbitkow[miliony][1] - 1;
            ptr = (int32_t *) & buforWyjscia[wypisanychBajtow];
            *ptr = *(int32_t *) zbitkiCyfr[tysiace][3];
            wypisanychBajtow += 3;
            ptr = (int32_t *) & buforWyjscia[wypisanychBajtow];
            *ptr = *(int32_t *) zbitkiCyfr[koncowka][3];
            wypisanychBajtow += 4;
        }

    }
    fwrite(buforWyjscia, 1, wypisanychBajtow, stdout);
}

Hardkorowe wczytywanie i wypisywanie danych :P Powinno przydać się do innych zadań. No chyba, że ktoś ma szybsze.

0

OK. Udało mi się zaprząc hash_mapę do pracy :)

#include <cstdio>
#include <ext/hash_map>
#include <vector>

int main(int argc, char** argv) {

    int _, iloscWierszy;
    _ = scanf("%d", &iloscWierszy);

    __gnu_cxx::hash_map<int, int> ilosci;
    std::vector<int> produkty;

    for (int wiersz = 0; wiersz < iloscWierszy; wiersz++) {
        int produkt, ilosc;
        _ = scanf("%d %d", &produkt, &ilosc);
        if (ilosci.count(produkt) > 0) {
            ilosci[produkt] += ilosc;
        } else {
            produkty.push_back(produkt);
            ilosci[produkt] = ilosc;
        }
    }

    printf("%zu\n", produkty.size());
    for (std::vector<int>::const_iterator produkt = produkty.begin(); produkt != produkty.end(); ++produkt) {
        printf("%d %d\n", *produkt, ilosci[*produkt]);
    }
}

Niestety i tak chyba wolniejsza od mojej hash_mapy.

0

A zaciekawił mnie tamat. ;)

Wibowit napisał(a)

Nie widać, że zrobiłem wersję z własną hashmapą? Złożoność oczekiwana mojej najlepszej wersji to O(n). Hashmapy z STLa nie wiem jak użyć :P

To ma dziwna złożoność. ;) Dopisałem takie coś:

        while ((mapa[hash].numer ^ numer) > 0) {
            hash = (hash + 1) & (MaxProduktow - 1);
            IleTutaj++;
        }

Trzy przypadki. Policzyłem wyszło mi 1195043, dla 603393 różnych produktów, 85432951 dla 994372, oraz 122226723 dla 999433 różnych produktów.
Ilość produktów 1000000.
Czas wykonania całości po kolej: 0.46 1.16 1.32 , w zasadzie do połowy różnych ma złożoność całkiem fajną a potem już mniej fajną ;)

A więc zwiększając haszmape (np. dwukrotnie), powinno się uzyskać lepszy rezultat. O ile dobrze myśle ;) Bo sam nie wiem teraz ;)
Zależy od typu danych jakie program dostaje.
.

0

Jeszcze jedno pytanie ^^ gdzie w kodzie dragona jest błąd? bo dopatrzyć się nie mogę a dane są ok na moje oko.

0

Nie będę zakładał nowego tematu to napisze tu ^^ Dacie jakieś wskazówki do rozwiązania tego https://pl.spoj.pl/problems/BALANCE/ mam już trochę kodu ale 1 i 3 nie przechodzi ;/ Działa tylko dla tych łatwiejszych ponieważ nie mogę wymyślić jak obliczyć gdy jest bardziej złożone ;/

0

Witam, chciałem napisać kod z urzyciem listy jednokierunkowej. Wydawało mi się, że to jest najszybszy sposób jednak jak się okazuje kod nie przechodzi testu szybkości. Co w danym przykładzie można poprawić adby zwiekszyć szybkość działania programu?

#include <stdio.h>
#include <stdlib.h>

struct lista
{
	int A, K;
	struct lista *next;
};

void show(struct lista *p)
{
	while(p != NULL)
	{
		printf("%d %d\n", p->A, p->K);
		p = p->next;
	}
}

int insert(struct lista **l, struct lista *p)
{
	if(!(*l))
	{
		*l = p;
		return 1;
	}
	
	if(p->A != (*l)->A) return insert(&(*l)->next, p);
	else
	{
		(*l)->K += p->K;
		return 0;
	}
}

int main()
{
	int n, i, m = 0;
	struct lista *l = NULL, *p;
	
	scanf("%d", &n);
	p = malloc(n * sizeof(struct lista));
	
	for(i=0; i<n; i++)
	{
		scanf("%d %d", &(p+i)->A, &(p+i)->K);
		(p+i)->next = NULL;
	}
	
	for(i=0; i<n; i++)
	{
		/*p = malloc(sizeof(struct lista));
		p->next = NULL;
		
		scanf("%d %d", &p->A, &p->K);*/
		
		m += insert(&l, p+i);
	}
	printf("%d\n", m);
	show(l);
	
	return 0;
}

Pozdrawiam mateusz

0
mateusz4 napisał(a)

[...]Co w danym przykładzie można poprawić adby zwiekszyć szybkość działania programu?[...]
-dla danych na SPOJu napisane własnego buforowanego printf i scanf to jakieś 6 sekund zysku
-czemu służy pierwsza pętla w main? przecie wystarczy ta druga
-lista to zły pomysł bo złożoność ma kwadratową
funkcję insert zawołasz może i nawet 500 miliardów razy
-analogiczny program można zapisać tak:

int t[1000001][2];  // danych nie więcej niż....

main(){
	int L=0,n,a,b,i;
	scanf("%d",&n);
	while(n--){
		scanf("%d %d", &a, &b);
		t[L][0]=a;
		i=0;
		while(t[i][0]!=a)    // danych przybywa
			i++;         // coraz dłużej i dł....
		if(i==L) t[L++][1]=b;
		else t[i][1]+=b;
	}
	printf("%d\n", L);
	for(i=0;i<L;i++)
		printf("%d %d\n", t[i][0], t[i][1]);
	return 0;
}
0

Nie będę zakładał nowego tematu bo po co skoro i tak ten dotyczy zadania ze SPOJA a ja mam pytanie odnośnie zadania z niego. Mianowicie : Mam taki kod


#include <iostream>
using namespace std;

int wyn[1500000];
int main(void)
{   
	int n,m,k,w,l,sp,ii,ww;
        ii=0;
	ww=0;

	cin >> n;
	
	while(n)
	{	   
	   cin >> m >> k;
	   ww=0;

	   while(k)
	   {      
        	  cin >> w >> l >> sp;
		   
                 if(w>l)
		   {
			   for(int i=w;i>l;i--)
			   {
				   ww+=sp;
			   }
		   }
		   else
		   {
              for(int i=w;i<l;i++)
			  {
				  ww+=sp;
			  }
		   }
		    if(k-1==0)
		    {
			   wyn[ii]=ww;
			   ii++;
		    } 
		   k--;
	   }

		n--;
	}
	
	for(int i=0;i<ii;i++)
	{
		cout << wyn[i] << endl;
	}
	return 0;
} 

Dla tego zadania http://pl.spoj.pl/problems/XIWTPZD/ i nie wiem gdzie jest błąd... Coś mi się zdaje że źle zrozumiałem to zadanie bo liczyłem i wynik to 295 więc jak z tego wychodzi 320?

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