Nguồn đề bài: http://www.spoj.com/PTIT/problems/P152PROE/
1. Đề bài P152PROE spoj PTIT
Cho 1 dãy số gồm n số nguyên a[1], a[2], …, a[n]. Đếm số cách chia dãy thành 3 phần bằng nhau, hay nói cách khác là đếm số cặp i, j thỏa mãn:
![]()
Input
Dòng đầu tiên chứa số n (1 ≤ n ≤ 5*10^5).
Dòng thứ 2 gồm n số nguyên a[1], a[2], …, a[n] (0 <= |a[i]| <= 10^9) là các phần tử của dãy.
Output
In ra kết quả của bài toán.
Example
Test 1:
Input:
5
1 2 3 0 3
Output:
2
Test 2:
Input:
2
4 1
Output:
0
2. Gợi ý P152PROE spoj PTIT
Problem E: Đếm số cách
Gọi sum là tổng của tất cả các phần tử trong dãy:
Nếu sum % 3 != 0, trường hợp này bỏ qua, in ra 0.
Tại vị trí i mà tại đó tổng từ 1 đến i = sum/3, tính tổng số lượng các phần tử vị trí j (i < j <= n)
sao cho tổng từ j đến n = sum/3. Cộng dồn tổng vừa tìm được vào kết quả.
Để xử lý phần tìm số lượng vị trí j, ta có thể chuẩn bị trước 1 mảng bằng QHĐ (Mảng tổng).
3. code tham khảo P152PROE spoj PTIT
a. Code c++
#include <iostream>
using namespace std;
long long sum[500010];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
int n1;
cin >> n1;
sum[i] = sum[i - 1] + n1;
}
long long tong = 0;
if (sum[n] % 3 == 0)
{
int dem = 0;
for (int i = n - 1; i>0; i--)
{
if (sum[i] == sum[n] / 3)
{
tong = tong + dem;
}
if (sum[i] == sum[n] / 3 * 2)
{
dem++;
}
}
}
cout << tong << endl;
}b. Code pascal
const fi='';
nmax=5*100000;
type data=longint;
var
f:text;
A,dem:array[0..nmax+1] of int64;
n:data; res:int64;
procedure docfile;
var
i,j:data;
x:int64;
begin
assign(f,fi); reset(f);
readln(f,n);
a[0]:=0;
for i:=1 to n do
begin
read(f,x);
a[i]:=a[i-1]+x;
end;
close(f);
end;
procedure xuli;
var i,j:data;
dem:int64;
begin
res:=0; dem:=0;
if a[n] mod 3 <>0 then exit;
for i:=n-1 downto 1 do
begin
if a[n] div 3 = a[i] then
inc(res,dem);
if (a[n] div 3)*2 = a[i] then
inc(dem)
end;
end;
begin
docfile;
xuli;
writeln(res);
end.