Olympic Bắc Giang 2012 - Bảng B.
Có M phần thưởng chia cho N học sinh giỏi được xếp hạng từ 1 đến N. Tính số cách chia phần thưởng sao cho thỏa mãn các điều kiện sau:
- Số phần thưởng của học sinh hạng i phải lớn hơn hoặc bằng số phần thưởng của học sinh hạng j nếu j>i
- Tất cả các phần thưởng phải được chia hết cho học sinh
Dữ liệu vào: Lấy từ tệp databai4.inp gồm 2 dòng. Dòng 1 ghi số M (M>=1). Dòng thứ 2 ghi N (N<=50).
Kết quả: Ghi các cách chia vào tệp kqbai4.out. Mỗi cách chia ghi trên một dòng, mỗi dòng có N giá tri, mỗi giá trị là số phần thưởng nhận được tương ứng của từng học sinh được xếp hạng từ 1 đến N. Các giá trị ghi trên 1 dòng cách nhau 1 dấu cách. Dòng cuối cùng ghi số cách chia phần thưởng tìm được.
Giải
const
fi='nhap.txt';
fo='xuat.txt';
max=100;
var
n,m,q: integer;
x,t: array[0..max] of integer;
f: text;
procedure Nhap;
begin
assign(f,fi);
reset(f);
readln(f,m,n);
close(f);
x[0]:=1;
t[0]:=0;
end;
procedure Xuat(k: integer);
var
i,tg,j,s: integer;
begin
s:=0;
for i:=1 to k do
for j:=k downto 1 do
if (x[i]<=x[j])and(j>=i) then
begin
tg:=x[i];
x[i]:=x[j];
x[j]:=tg;
end;
for i:=1 to k do s:=s+x[i];
if s=m then
begin
for i:=1 to k do write(f,x[i],' ');
for i:=k+1 to n do write(f,'0 ');
writeln(f);
q:=q+1;
end;
end;
procedure Try(i: integer);
var
j: integer;
begin
for j:=x[i-1] to (m-t[i-1]) div 2 do
begin
x[i]:=j;
t[i]:=t[i-1]+x[i];
Try(i+1);
end;
x[i]:= m-t[i-1];
if i<=n then Xuat(i);
end;
begin
Nhap;
assign(f,fo);
rewrite(f);
Try(1);
write(f,q);
Close(f);
end.
No comments:
Post a Comment
Cảm ơn bạn đã nhận xét