• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Zadanie Grzybki ILOCAMP

Object Storage Arubacloud
0 głosów
559 wizyt
pytanie zadane 12 lutego 2023 w C i C++ przez polandonion Mądrala (7,040 p.)
otwarte ponownie 25 lutego 2023 przez polandonion

Siema, pomoze ktos z kodem?

Najprawdopodobniej robie jakims dziwnym sposobem dla Was i mam prosbe o ewentualne nakierowanie.

zadanie: https://szkopul.edu.pl/problemset/problem/UDIADIj0TZR7zMUXeF6XlM1T/site/?key=statement

#include <bits/stdc++.h>

using namespace std;

struct Grzyb {
	int mas, del, dni;
	// mas - masa grzyba, del - przyrost, dni - ilosc dni zycia
};

Grzyb arr[1000001];
unordered_map <int, pair <long long, int>> m;

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	int n;
	cin >> n;

	int maxDz = 0, dz = 1;
	// dz - wynik (optymalny dzien)

	long long sum = 0, su = 0, prz = 0;
	// sum - zmienna pomocnicza

	for (int i = 1; i <= n; i ++) {
		cin >> arr[i].mas >> arr[i].del >> arr[i].dni;
		// wczytanie danych

		su += arr[i].mas;
		// suma grzybow w dniu 0.

		maxDz = max(maxDz, arr[i].dni);
		// jaki jest max dzien do sprawdzenia w symulacji

		m[arr[i].dni].first += (arr[i].dni - 1) * arr[i].del + arr[i].mas;
		// suma (mas poczatkowych oraz doladowywanych
		// z dnia na dzien), ktore umieraja w dniu arr[i].dni (*)

		m[arr[i].dni].second += arr[i].del;
		// suma mas grzybow, ktore umieraja w dniu arr[i].dni (**)

		prz += arr[i].del;
		// przyrost z dnia na dzien
	}

	for (int i = 1; i <= maxDz; i ++) {
		su += prz;
		// za kazdym razem dodaje przyrost

		if (m.find(i) != m.end())
			su -= m[i].first + m[i].second, prz -= m[i].second;
			// jezeli jakas ryba/ryby umiera w dniu i, to od su odejmuje
			// (*) oraz (**), jednoczesnie aktualizujac przyrost

		if (su > sum)
			sum = su, dz = i;
			//sprawdzam, czy aktualna suma nie jest najlepsza i aktualizuje sume i dzien
	}

	cout << dz;// << ' ' << sum;
}

 

1 odpowiedź

+1 głos
odpowiedź 12 lutego 2023 przez pasjonat_algorytmiki Pasjonat (19,540 p.)
wybrane 12 lutego 2023 przez polandonion
 
Najlepsza
A to tu nie wchodzi jakieś proste O(N)?

Sortujesz counting sortem(jak posortujesz normalnie, to dostaniesz O(N lg N)) kandydatów na dzień zbioru grzybów, i sprawdzasz wszystkich kandydatów. Jak sprawdzasz pojedyńczego kandydata, to zakładając, że jest to moment x, to sprawdzasz momenty x oraz x-1(przed i po zebraniu), trzymasz zmienną suma wszystkich o ile wzrasta. Sumujesz liniowo, naiwnie z wejścia i mnożysz przez ile dni, na bierząco. Jeżeli zdejmujesz element Z, to odejmujesz od sumy i będziesz mnożył mniej grzybów.

Wydaje się to takie wmiarę intuicyjne.

Myślę, że jakaś podpucha autora polegała na tym, że N <= 10^6 i ktoś nie zauważy, że d_i <= 10^5 i zrobi sorta w O(N lg N) i nie przejdzie mu czas, tylko np wejdzie na jakieś 80pkt.

Btw. Wczytując d_i odjałbym na starcie dla czytelności kodu 1, bo tam jak np d_i = 4, to dodaje do dnia 3, a nie 4. Ale to już kwestia implementacji

Abstrahując od tego, że poleciłbym najpierw napisać dla treningu bruta, gdzie dla każdego kandydata sprawdzasz naiwnie. O(N^2)
komentarz 13 lutego 2023 przez polandonion Mądrala (7,040 p.)

Wiesz co, myślałem, że mój sposób jest jakiś zwalony, ale okazało się, że C++ czasami dziwnie konwertuje int'a na long long'a i najprawdopodobniej podczas jakiejś konwersji najpierw zamienił mi jakąś zmienną na int'a a dopieo potem na long long'a i dlatego wynik ucierpiał. Teraz wszystko działa, lecz nie na 100%, tylko 99. Jeden test przekracza czas o 0.01s.

Przyznam szczerze, że nie patrzyłem w twój kod, bo próbowałem zostać przy mojej wersji i opłaciło się. Oczywiście Twój może działać szybciej, ale nie zminia to faktu, że jakoś wolę prostsze implementacje.

A, no i dodam, że nie trzeba zapamiętywać dni x oraz x - 1 w jakimś wektorze. Przeprowadziłem pełną symulację i mój program działa dobrze. :D

Tak czy siak, dzięki za poświęcony czas nt. tego zadanka.

Wzorcówka:

#include <bits/stdc++.h>

using namespace std;

struct Grzyb {
	long long a, b, c;
    // a - masa, b - przyrost, c - dni zycia
};

unordered_map <int, pair <long long, long long>> m;
Grzyb a[1000001];

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    int n;
    cin >> n;

    long long su = 0, prz = 0, mxDz = 0;
    for (int i = 1; i <= n; i ++) {
    	cin >> a[i].a >> a[i].b >> a[i].c;

        mxDz = max(mxDz, a[i].c);

        su += a[i].a; // suma poczatkowa
        prz += a[i].b; // przyrost poczatkowy

        m[a[i].c].first += (a[i].c - 1) * a[i].b + a[i].a;
        m[a[i].c].second += a[i].b;
    }

    long long sum = 0, dz = 1;
    for (int i = 1; i <= mxDz; i ++) {
        su += prz;
        if (m.find(i) != m.end())
            su -= m[i].first + m[i].second, prz -= m[i].second;

        //cout << su << ' ';
        if (su > sum)
            sum = su, dz = i;
    }

    cout << dz;
}
komentarz 13 lutego 2023 przez pasjonat_algorytmiki Pasjonat (19,540 p.)
Masz rację, nie trzeba trzymać kandydatów w vectorze, bo d_i <= 10^5, więc twój kod jest lepszy niż mój (robią praktycznie to samo, tylko że mój ma kandydatów i sprawdza x i x-1, a twój korzysta z tego, że moze sprawdzić wszystkie d_i). Ale zwróc uwage, że twój kod nie zadziała dla d_i <= 10^9, a mój tak, a mają taką samą złożonność
komentarz 13 lutego 2023 przez polandonion Mądrala (7,040 p.)
edycja 13 lutego 2023 przez polandonion

Teraz wszystko działa, lecz nie na 100%, tylko 99. Jeden test przekracza czas o 0.01s.

komentarz 13 lutego 2023 przez pasjonat_algorytmiki Pasjonat (19,540 p.)
w strukturze grzyb masz long longi, zmien na int-y. Chyba przyspieszy to wczytywanie. usun long longi, tam gdzie ich nie potrzebujesz
1
komentarz 13 lutego 2023 przez polandonion Mądrala (7,040 p.)
przyspieszyło o 0.25s, co wystarczyło do uzyskania setki. Dzięki wielkie

Podobne pytania

0 głosów
2 odpowiedzi 232 wizyt
pytanie zadane 5 lutego 2023 w C i C++ przez polandonion Mądrala (7,040 p.)
+1 głos
1 odpowiedź 251 wizyt
0 głosów
0 odpowiedzi 66 wizyt
pytanie zadane 24 października 2023 w C i C++ przez kamilek1234 Nowicjusz (120 p.)

92,568 zapytań

141,422 odpowiedzi

319,629 komentarzy

61,956 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...