Wyznaczenie minimalnej liczby rozłączych przedziałów, których suma jest ustalona (zad. z MAIN)

0

Witam.
Mam problem z opracowaniem algorytmu, który w zasadzie ma robić to, co widnieje w nazwie tematu, natomiast szczegóły i źródło to: main.edu.pl/pl/user.phtml?op=showtask&task=prze&con=PAS

Napisałem taki (mam nadzieję, że algorytm może być przedstawiony w zapisie a'la C++)
UWAGI: przedz[i][0] oraz przedz[i][1] to kolejno: początek i koniec i-tego przedziału (i przebiega od 0 do n-1); ile_rozl to szukana liczba

 ile_rozl = 1;
    aktualny_koniec = przedz[0][1];
    for( i = 0; i < n ; ++i)
    {
                 if(i)
                 {
                      if(przedz[i][1] <= aktualny_koniec) continue;
                 }
                 bool czy_zachodzi = false;
                 for( j = i + 1; j < n; ++j)
                 {
                              if(przedz[j][0] <= aktualny_koniec + 1 && przedz[j][1] >= aktualny_koniec + 1) 
                              {
                                                                      czy_zachodzi = true;
                                                                      aktualny_koniec = przedz[j][1];
                                                                      i = j - 1;
                                                                      break;
                              }
                 }
                 if(!czy_zachodzi)
                 {
                                  ile_rozl++;
                                  for(k = i + 1; k < n; ++k)
                                  {
                                               if( przedz[k][1] >= aktualny_koniec + 1)
                                               {
                                                   aktualny_koniec = przedz[k][1];
                                                   i = k;
                                                   break;
                                               }
                                  } 
                 }
    } 

Daje on błędne odpowiedzi...
Proszę o pomoc, jak go naprawić, tudzież napisać inny.

0

Jako przykład podano:{[-2,2], [6,6], [0,3], [5,5]} odpowiedzią ma być {[-2,3], [5,6]}nie rozumiem czemu nie {[-2,3], [5,5], [6,6]}

0

Udało mi się ciut ulepszyć powyższy kod - wcześniej sprawdzarka dawała 40/100, a teraz 70/100, więc nadal coś jest nie tak...
Kod po poprawce:

 ile_rozl = 1;
    aktualny_koniec = przedz[0][1];
    for( i = 0; i < n - 1; ++i)
    {
                 bool czy_zachodzi = false;
                 for( j = i + 1; j < n; ++j)
                 {
                              if(przedz[j][0] <= aktualny_koniec + 1 && przedz[j][1] >= aktualny_koniec + 1)
                              {
                                              czy_zachodzi = true;
                                              aktualny_koniec = przedz[j][1];
                                              i = j - 1;
                                              break;
                              }
                 }
                 if(!czy_zachodzi)
                 {
                                  ile_rozl++;
                                  for( k = i + 1; k < n; ++k)
                                  {
                                               if(przedz[k][1] >= aktualny_koniec + 2)
                                               {
                                                               aktualny_koniec = przedz[k][1];
                                                               i = k - 1;
                                                               break;
                                               }
                                  }
                 }
    } 

Czy jest potrzeba abym wyjaśniał, co która linijka ma za zadanie zrobić, czy jest to raczej jasne? Starałem się pisać takie nazwy zmiennych, żeby jednak mówiły coś o sobie : )

Aha, chyba nie napisałem - pisząc w 1. poście, że przedz[i][] to i-ty przedział, miałem na myśli i-ty przedział w kolejności względem początków przedziałów (tj. są już posortowane względem początków)

0

{{6,7},{3,4},{5,6},{1,2}} - dla tych danych twój algorytm pokaże 4, a ma być 1.

0

Nieprawda - pokazuje 1, więc prawidłowo.
Zresztą, można samemu uruchomić i sprawdzić; cały kod programu:

#include <iostream>
using namespace std;

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    
    unsigned short n;
    cin >> n;
    
    int **przedz = new int*[n];
    for(unsigned short i = 0; i < n; ++i)
    {
                 przedz[i] = new int[2];
    }
    for(unsigned short i = 0; i < n; ++i)
    {
                 cin >> przedz[i][0] >> przedz[i][1];         
    }
    for(unsigned short j = 1; j < n; j++) // sortujemy poczatki przedzialow
    {
             int klucz1 = przedz[j][0];
             int klucz2 = przedz[j][1];        
             int i = j - 1;
             while( i >= 0 && przedz[i][0] > klucz1 )
             {
                    przedz[i + 1][0] = przedz[i][0];
                    przedz[i + 1][1] = przedz[i][1];
                    i--;
             }
             przedz[i + 1][0] = klucz1;
             przedz[i + 1][1] = klucz2;
    }
    
    unsigned short ile_rozl = 1;
    int aktualny_koniec = przedz[0][1];
    for(unsigned short i = 0; i < n - 1; ++i)
    {
                 bool czy_zachodzi = false;
                 for(unsigned short j = i + 1; j < n; ++j)
                 {
                              if(przedz[j][0] <= aktualny_koniec + 1 
                              && przedz[j][1] >= aktualny_koniec + 1)
                              {
                                              czy_zachodzi = true;
                                              aktualny_koniec = przedz[j][1];
                                              i = j - 1;
                                              break;
                              }
                 }
                 if(!czy_zachodzi)
                 {
                                  ile_rozl++;
                                  for(unsigned short k = i + 1; k < n; ++k)
                                  {
                                               if(przedz[k][1] >= aktualny_koniec + 2)
                                               {
                                                               aktualny_koniec = przedz[k][1];
                                                               i = k - 1;
                                                               break;
                                               }
                                  }
                 }
    }
    cout << ile_rozl << endl;
    for(unsigned short j = 0; j < n; j++)
    {
                 delete [] przedz[j];
    }
    delete [] przedz;
} 

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