- greutatea totală suportată de o barcă este
C; - dacă în barcă se aşază două persoane, atunci diferența în modul dintre greutățile acestora trebuie să fie maxim
B, în caz contrar barca nu este balansată și riscă să se răstoarne.
Dacă o singură persoană se aşază în barcă, nu se aplică restricția a doua.
Cerința
Care este numărul minim de bărci necesare pentru a putea plimba toţi elevii în condiţii de siguranţă?
Date de intrare
Fișierul de intrare barci.in conţine pe prima linie trei numere naturale separate prin spaţiu: N, C și B, reprezentând numărul de elevi, capacitatea maximă a unei bărci şi respectiv diferenţa maximă dintre greutatea a două persoane care se pot aşeza în aceeaşi barcă. Pe a doua linie se află N numere naturale separate prin spaţiu w[i] (1 ≤ i ≤ N), reprezentând greutăţile celor N elevi.
Date de ieșire
Fișierul de ieșire barci.out va conţine o singură linie pe care va fi scris numărul minim de bărci necesare.
Restricții și precizări
1 ≤ N ≤ 100 0001 ≤ w[i] ≤ C ≤ 1 000 000 000, pentru1 ≤ i ≤ N0 ≤ B ≤ 1 000 000 000- Pentru teste în valoare de
30de puncte,N ≤ 10 - Pentru teste în valoare de
60de puncte,N ≤ 1000
Exemplu
barci.in
8 100 10 81 37 32 88 55 93 45 72
barci.out
6
Explicație
Configuraţia celor 6 bărci poate fi următoarea:
1: (81)
2: (37, 32) deoarece 37+32 ≤ 100 şi 37-32 ≤ 10
3: (88)
4: (55, 45) deoarece 55 + 45 ≤ 100 şi 55 – 45 ≤ 10
5: (93)
6: (72)
Cum e corect?
cout < "As la info";
cout << "As la info";
cout >> "As la info";
Felicitări! Poți mai mult?
Avem sute de probleme pentru tine, fiecare cu explicații ușor de înțeles.
Greșit, dar nu-i bai!
Antrenează-te cu sutele de probleme pe care ți le-am pregătit. Îți explicăm fiecare problemă în parte.
Rezolvare
Iată rezolvarea de 100 de puncte pentru problema barci:
//Paul Diac 100
#include <cstdio>
#include <string>
#include <cassert>
#include <cstdlib>
#define NMax 1000000
using namespace std;
int T = 10;
int N, C, B;
int v[NMax];
struct man {
int w, prev, next, barked;
};
man o[NMax];
int compDesc(const void *a, const void *b) {
return *(int*)b - *(int*)a;
}
int validTogether(int i, int j) {
return (0 <= i && i < N && 0 <= j && j < N && o[i].barked == 0 && o[j].barked == 0 &&
i < j && o[i].w + o[j].w <= C && o[i].w - o[j].w <= B && o[j].w - o[i].w <= B);
}
void remove(int &idx) {
o[idx].barked = 1;
o[o[idx].prev].next = o[idx].next;
o[o[idx].next].prev = o[idx].prev;
idx = o[idx].next;
}
int main() {
string fname = "barci";
FILE *fin = fopen((fname + ".in").c_str(), "rt");
FILE *fout = fopen((fname + ".out").c_str(), "wt");
fscanf(fin, "%d %d %d", &N, &C, &B);
assert(N <= 100000);
assert(C <= 1000000000);
assert(B <= 1000000000);
assert(1 <= N);
assert(1 <= C);
assert(0 <= B);
for (int i = 0; i < N; i++) {
fscanf(fin, "%d", &v[i]);
assert(v[i] <= v[i]);
assert(1 <= v[i]);
}
qsort(v, N, sizeof(v[0]), compDesc);
for (int i = 0; i < N; i++) {
o[i].w = v[i];
o[i].next = i+1;
o[i].prev = i-1;
o[i].barked = 0;
}
o[N].prev = N-1;
int left;
for (left = N-1; left >= 0 && o[0].w + o[left].w <= C; left--);
left++; // left end of interval with valid pair of current man
int boats = 0;
for (int i = 0; i < N; i++) if (!o[i].barked) {
if (left == i) {
left = o[left].next;
}
// left is always on the right (and smaller than) i.
// and all left of i are barked
while (o[left].prev > i && o[i].w + o[o[left].prev].w <= C) {
left = o[left].prev;
}
if (validTogether(i, left)) {
//fprintf(fout, "%d %d\n", o[i].w, o[left].w);
remove(left);
}
o[i].barked = 1;
boats++;
}
fprintf(fout, "%d\n", boats);
fclose(fin);
fclose(fout);
return 0;
}
Atenție
Enunțurile afișate pe această pagină aparțin exclusiv site-ului PbInfo. Astfel, pentru ștergerea conținutului, puteți să ne contactați la adresa
.
Rezolvarea problemei #2186 barci
Pe această pagină găsești rezolvarea de 100 de puncte pentru problema #2186 barci de pe PbInfo.ro. Atenție: nu încurajăm copiatul codului! Totuși, credem cu tărie că analizarea unei soluții corecte este o metodă foarte ușoară de a învăța informatică, astfel că oferim sursele pentru peste 1500 de probleme de pe platforma PbInfo.ro.
Pentru rezolvări PbInfo de la peste 1500 de probleme, vă invităm să intrați pe site-ul nostru!