9.29.2017

Chia phần thưởng

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