Algoritmul, pas cu pas
Cheia tuturor cerințelor sunt sumele prefix: , cu . Atunci și suma totală e .
Cerința 1 — punct de echilibru. devine . Parcurg de la la și caut prima poziție unde egalitatea ține.
Cerința 2 — sărim elementul . devine . Parcurg de la la .
Cerința 3 — trei bucăți egale, sărind și .
- Condiția e .
- Pentru fiecare , partea stângă e . Ca partea dreaptă să fie egală, am nevoie de .
- Cum prefixele cresc strict (toate ), există cel mult un singur cu acea valoare — îl găsesc prin căutare binară.
- Verific apoi că bucata din mijloc e egală cu și că . Returnez prima pereche găsită.
Complexitate: pentru cerințele 1 și 2, pentru cerința 3.
Soluția în C++
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("zudt.in");
ofstream fout("zudt.out");
int main() {
int C, N;
fin >> C >> N;
vector<long long> P(N + 1, 0);
for (int k = 1; k <= N; k++) {
long long x;
fin >> x;
P[k] = P[k - 1] + x; // sume prefix
}
long long Total = P[N];
if (C == 1) {
int ans = 0;
for (int i = 1; i < N && ans == 0; i++)
if (P[i] == Total - P[i]) ans = i;
fout << ans << "\n";
} else if (C == 2) {
int ans = 0;
for (int i = 2; i < N && ans == 0; i++)
if (P[i - 1] == Total - P[i]) ans = i;
fout << ans << "\n";
} else { // C == 3
int fi = 0, fj = 0;
for (int i = 2; i <= N && fi == 0; i++) {
long long left = P[i - 1];
long long want = Total - left; // căutăm j cu P[j] = want
int lo = 1, hi = N, j = -1;
while (lo <= hi) {
int mid = (lo + hi) / 2;
if (P[mid] == want) { j = mid; break; }
else if (P[mid] < want) lo = mid + 1;
else hi = mid - 1;
}
// i+1 < j < N și bucata din mijloc egală cu left
if (j != -1 && i + 1 < j && j < N && P[j - 1] - P[i] == left) {
fi = i;
fj = j;
}
}
if (fi == 0) fout << 0 << "\n";
else fout << fi << " " << fj << "\n";
}
return 0;
}Greșeli frecvente
- Recalculezi sumele pentru fiecare poziție — cu până la asta dă și depășește timpul; folosește sume prefix și răspunde în pe poziție.
- Folosești
intpentru sume — suma poate atinge , care încape înint, dar la cerința 3 e mai sigurlong long; oricum, fii atent la tip. - Greșești marginile la cerința 3 — trebuie și ; dacă lași sau obții bucăți goale sau ieși din șir.