[Algorytmy][C++] SPOJ, przekroczony limit czasu

nnnmmm
Użytkownik
Użytkownik
Posty: 369
Rejestracja: 16 sty 2013, o 15:48
Płeć: Kobieta
Lokalizacja: Warszawa
Podziękował: 102 razy
Pomógł: 1 raz

[Algorytmy][C++] SPOJ, przekroczony limit czasu

Post autor: nnnmmm »

Witam męczę się z zadaniem
Niestety, każde z nich przekracza limit czasu. Pierwsze jest oparte na sortowaniu i wyszukiwaniu binarnym. Drugie na sortowaniu, wyszukiwaniu binarnym i coś na wzór hash_mapy.
1:

Kod: Zaznacz cały

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void wczytaj(vector<int> &b);

int main()
{
    int n,m;
    cin>>n>>m;
    vector<int> wag1(n);
    vector<int> wag2(n);
    vector<int> zapytania(m);
    vector<string> odp;

    wczytaj(wag1);
    wczytaj(wag2);
    wczytaj(zapytania);

    sort(wag2.begin(),wag2.end());
    sort(wag1.begin(),wag1.end());

    for(int i=0;i<m;i++)
    {

        for(int k=0;k<n;k++)
        {

            int szukane=zapytania[i]-wag1[k];
            int szukane2=zapytania[i]-wag2[k];

            if(szukane<=0 || szukane2<=0)
            {
                odp.push_back("NIE");
                break;
            }

            bool exist=binary_search(wag2.begin(),wag2.end(),szukane);
            bool exist2=binary_search(wag1.begin(),wag1.end(),szukane2);

            if(exist || exist2)
               {
                   odp.push_back("TAK");
                   break;
               }
              else if((!exist || !exist2) && k==n-1)
              {
                  odp.push_back("NIE");
              }
    }
    }


    for(int i=0;i<odp.size();i++)
    {
        cout<<odp[i]<<endl;
    }
}


void wczytaj(vector<int> &b)
{
    for(int i=0;i<b.size();i++)
    {
        int liczba;
        cin>>liczba;
        b[i]=liczba;

    }
}

2:

Kod: Zaznacz cały

#include <iostream>
#include <vector>
#include<algorithm>

using namespace std;

void wczytaj(vector<int> &b);
void wczytaj2(int a,vector<int> &b);

int main()
{
    int n,m;
    cin>>n>>m;
    vector<int> wag1(n);
    vector<int> wag2(100000000);
    vector<int> zapytania(m);
    vector<string> odp;

    wczytaj(wag1);
    wczytaj2(n,wag2);
    wczytaj(zapytania);

sort(wag1.begin(),wag1.end());

    for(int i=0;i<m;i++)
    {

        for(int k=0;k<n;k++)
        {
            //szukane-liczba z wa2 taka, że wag1+wag2=szukane

            int szukane=zapytania[i]-wag1[k];
            
            if(szukane<=0)
            {
                 odp.push_back("NIE");
                 break;
            }

            if(wag2[szukane-1]==szukane)
            {
                odp.push_back("TAK");
                break;
            }
            else if(wag2[szukane-1]!=szukane && k==n-1)
            {
                odp.push_back("NIE");

            }

    }
    }

    for(int i=0;i<odp.size();i++)
    {
        cout<<odp[i]<<endl;
    }

}

void wczytaj(vector<int> &b)
{
    for(int i=0;i<b.size();i++)
    {
        int liczba;
        cin>>liczba;
        b[i]=liczba;

    }
}
//tworzy cos na wzor hash mapy czyli licza=5, leci do komorki o nr 4(bo liczymy indeksy od 0)
void wczytaj2(int a, vector<int> &b)
{
    for(int i=0;i<a;i++)
    {
        int liczba;
        cin>>liczba;
        b[liczba-1]=liczba;

    }

}
Ostatnio zmieniony 14 paź 2015, o 22:23 przez Afish, łącznie zmieniany 1 raz.
Powód: Poprawa wiadomości.
norwimaj
Użytkownik
Użytkownik
Posty: 5101
Rejestracja: 11 mar 2011, o 16:31
Płeć: Mężczyzna
Lokalizacja: 52°16'37''N 20°52'45''E
Podziękował: 4 razy
Pomógł: 1001 razy

[Algorytmy][C++] SPOJ, przekroczony limit czasu

Post autor: norwimaj »

Zadanie nie polega na tym, żeby przeszukać wszystkie możliwe pary. Załóżmy, że masz tablicę dwuwymiarową, w której wszystkie wiersze i wszystkie kolumny są posortowane rosnąco. Ile elementów tablicy wystarczy obejrzeć, żeby wyszukać jakiś zadany element?
nnnmmm
Użytkownik
Użytkownik
Posty: 369
Rejestracja: 16 sty 2013, o 15:48
Płeć: Kobieta
Lokalizacja: Warszawa
Podziękował: 102 razy
Pomógł: 1 raz

[Algorytmy][C++] SPOJ, przekroczony limit czasu

Post autor: nnnmmm »

Jeśli mamy dwuwymiarową tablicę, to tak długo aż pierwsza współrzędna jest \(\displaystyle{ \le}\) szukanej sumie. No ale wraz ze wzrostem szukanej sumy, rośnie liczba elementów w tablicy które będziemy przeszukiwać...
norwimaj
Użytkownik
Użytkownik
Posty: 5101
Rejestracja: 11 mar 2011, o 16:31
Płeć: Mężczyzna
Lokalizacja: 52°16'37''N 20°52'45''E
Podziękował: 4 razy
Pomógł: 1001 razy

[Algorytmy][C++] SPOJ, przekroczony limit czasu

Post autor: norwimaj »

Konkretnie, ile elementów trzeba przejrzeć, jeśli tablica jest rozmiaru \(\displaystyle{ m\times n}\)?
nnnmmm
Użytkownik
Użytkownik
Posty: 369
Rejestracja: 16 sty 2013, o 15:48
Płeć: Kobieta
Lokalizacja: Warszawa
Podziękował: 102 razy
Pomógł: 1 raz

[Algorytmy][C++] SPOJ, przekroczony limit czasu

Post autor: nnnmmm »

Nie wiem.
norwimaj
Użytkownik
Użytkownik
Posty: 5101
Rejestracja: 11 mar 2011, o 16:31
Płeć: Mężczyzna
Lokalizacja: 52°16'37''N 20°52'45''E
Podziękował: 4 razy
Pomógł: 1001 razy

[Algorytmy][C++] SPOJ, przekroczony limit czasu

Post autor: norwimaj »

Źle, że użyłem litery \(\displaystyle{ m,}\) która w treści zadania oznacza co innego, ale na razie załóżmy, że tablica jest rozmiaru \(\displaystyle{ m\times n}\)

Jeśli przejrzymy wszystkie \(\displaystyle{ m\cdot n}\) elementów, to na pewno wystarczy. Ale wyobraź sobie, że za każde zobaczenie elementu w tablicy trzeba płacić \(\displaystyle{ 1\,\text{zł}.}\) Wtedy wolelibyśmy rozwiązywać zadanie nie poznając wszystkich wartości w tabeli.

W Twoim rozwiązaniu patrzymy na trochę mniej elementów. W każdym z \(\displaystyle{ m}\) wierszy stosujemy wyszukiwanie binarne, czyli patrzymy na \(\displaystyle{ O(m\log n)}\) elementów. Ale da się jeszcze mniej.
nnnmmm
Użytkownik
Użytkownik
Posty: 369
Rejestracja: 16 sty 2013, o 15:48
Płeć: Kobieta
Lokalizacja: Warszawa
Podziękował: 102 razy
Pomógł: 1 raz

[Algorytmy][C++] SPOJ, przekroczony limit czasu

Post autor: nnnmmm »

Czy do tego momentu mój kod jest poprawny?. Bo nie wiem czy mam cały algorytm przebudować, czy tylko pokombinować z modyfikacją szukania binarnego. Czy szukanie binarne jest tutaj złym rozwiazaniem? Jaki algorytm będzie odpowiedni?

Kod: Zaznacz cały

//nie trzeba przeszukiwać ZAWSZE wszystkich kolumn, ale czasami tak
int szukana_wartosc_w_wag2=szukana_suma[i]-wag1[k];

 if(szukana_wartosc_w_wag2<=0)
            {
                odp[i]="NIE";
                break;
            }
Wydaje mi się, że szukanie binarne w ogóle nie ma sensu w tym zadaniu. U góry(Pierwszy post i drugi kod) skrobnąłem coś na wzór tablicy haszującej i to też nie działa.

Jaka powinna być złożoność obliczeniowa rozwiązania, które masz na myśli?
norwimaj
Użytkownik
Użytkownik
Posty: 5101
Rejestracja: 11 mar 2011, o 16:31
Płeć: Mężczyzna
Lokalizacja: 52°16'37''N 20°52'45''E
Podziękował: 4 razy
Pomógł: 1001 razy

[Algorytmy][C++] SPOJ, przekroczony limit czasu

Post autor: norwimaj »

Nie jest powiedziane, że druga waga ma być mniejsza od 100000000. Twoja funkcja wczytaj2 może więc wyjść poza zakres.

Wracając do tematu, powiedzmy że w poniższej tablicy chcemy wyszukać liczbę 17. Oddzieliłem linią liczby mniejsze od 17 i większe lub równe 17. Jeśli liczba 17 istnieje w tabeli, to możemy ją znaleźć w sąsiedztwie tej linii. Jaką maksymalnie długość może mieć taka linia?

\(\displaystyle{ \begin{tabular}{|cccccc|}
\hline
3 & 4 & 7 & 10 & \multicolumn{1}{c|}{12} & 17\\
5 & 6 & 9 & 12 & \multicolumn{1}{c|}{14} & 19\\
\cline{5-5}
8 & 9 & 12 & \multicolumn{1}{c|}{15} & 17 & 22\\
\cline{4-4}
11 & 12 & \multicolumn{1}{c|}{15} & 18 & 20 & 25\\
\cline{3-3}
14 & \multicolumn{1}{c|}{15} & 18 & 21 & 23 & 28\\
\cline{1-2}
19 & 20 & 23 & 26 & 28 & 33\\
20 & 21 & 24 & 27 & 29 & 34\\
\hline
\end{tabular}}\)
nnnmmm
Użytkownik
Użytkownik
Posty: 369
Rejestracja: 16 sty 2013, o 15:48
Płeć: Kobieta
Lokalizacja: Warszawa
Podziękował: 102 razy
Pomógł: 1 raz

[Algorytmy][C++] SPOJ, przekroczony limit czasu

Post autor: nnnmmm »

W przypadku jak szukamy 17 to ma 7, tak? Długość jej jako liczba elementów granicznych tej linii? Tak?
norwimaj
Użytkownik
Użytkownik
Posty: 5101
Rejestracja: 11 mar 2011, o 16:31
Płeć: Mężczyzna
Lokalizacja: 52°16'37''N 20°52'45''E
Podziękował: 4 razy
Pomógł: 1001 razy

[Algorytmy][C++] SPOJ, przekroczony limit czasu

Post autor: norwimaj »

Nie do końca to miałem na myśli, ale niech będzie. Jaką największą długość może mieć taka linia, jeśli dane są tylko liczba wierszy i kolumn?
nnnmmm
Użytkownik
Użytkownik
Posty: 369
Rejestracja: 16 sty 2013, o 15:48
Płeć: Kobieta
Lokalizacja: Warszawa
Podziękował: 102 razy
Pomógł: 1 raz

[Algorytmy][C++] SPOJ, przekroczony limit czasu

Post autor: nnnmmm »

Jeśli tabelkę wymiarów \(\displaystyle{ n \times m}\) to pewnie \(\displaystyle{ n}\) albo \(\displaystyle{ m}\). Czyli coś jak liczba jest na środku koło przekątnej i dodatkowo wszystkie liczby w okolicy tej przekątnej są równe szukanej... No do końca nie wiem jak to uzasadnić... ale cos w tym stylu?
norwimaj
Użytkownik
Użytkownik
Posty: 5101
Rejestracja: 11 mar 2011, o 16:31
Płeć: Mężczyzna
Lokalizacja: 52°16'37''N 20°52'45''E
Podziękował: 4 razy
Pomógł: 1001 razy

[Algorytmy][C++] SPOJ, przekroczony limit czasu

Post autor: norwimaj »

To umiesz już wyszukać liczbę w takiej tabeli w czasie \(\displaystyle{ O(m+n)}\)?
nnnmmm
Użytkownik
Użytkownik
Posty: 369
Rejestracja: 16 sty 2013, o 15:48
Płeć: Kobieta
Lokalizacja: Warszawa
Podziękował: 102 razy
Pomógł: 1 raz

[Algorytmy][C++] SPOJ, przekroczony limit czasu

Post autor: nnnmmm »

Pewnie coś w stylu: bierzemy dwa wskaźniki(i), jeden doczepiamy do początku pierwszej tabeli, drugi do końca drugiej tabeli(j). Obie są posortowane, wiec jak suma współrzędnych z pary (i,j)<szukana , to i=i+1, jeśli (i,j)>szukana , to j=j-1. Hmmm, dobrze myślę? Jeszcze nie wpadłem na pomysł w którym momencie to zatrzymać i wypisać "NIE"
Ostatnio zmieniony 21 paź 2015, o 14:23 przez Afish, łącznie zmieniany 1 raz.
Powód: Poprawa wiadomości.
norwimaj
Użytkownik
Użytkownik
Posty: 5101
Rejestracja: 11 mar 2011, o 16:31
Płeć: Mężczyzna
Lokalizacja: 52°16'37''N 20°52'45''E
Podziękował: 4 razy
Pomógł: 1001 razy

[Algorytmy][C++] SPOJ, przekroczony limit czasu

Post autor: norwimaj »

nnnmmm pisze:Hmmm, dobrze myślę?
Piszesz z sensem, więc pewnie dobrze myślisz.
nnnmmm pisze:Jeszcze nie wpadłem na pomysł w którym momencie to zatrzymać i wypisać "NIE"
Wtedy, gdy wyjedziemy poza tabelę.
ODPOWIEDZ