[题目来源]:NOIP基础题目集
[关键字]:数学
[题目大意]:m个人拿50的去买票,n个人拿100的去买票,问有多少种能使钱找开的方案。
//============================================================================================================
[分析]:祥见《程序设计中的组合数学》P43页。此时若n = m则为Catalan数。
[代码]:
View Code
1 type
2 rec = record
3 len: longint;
4 dat: array[0..200] of longint;
5 end;
6 var
7 n, m, tot: longint;
8 ans: rec;
9 su, d: array[0..3000] of longint;
10
11 procedure cheng(var ans: rec; x: longint);
12 var
13 k, i: longint;
14 begin
15 k := 0;
16 for i := 1 to ans.len do
17 begin
18 ans.dat[i] := ans.dat[i]*x+k;
19 k := ans.dat[i] div 10000;
20 ans.dat[i] := ans.dat[i] mod 10000;
21 end;
22 while k > 0 do
23 begin
24 inc(ans.len);
25 ans.dat[ans.len] := k mod 10000;
26 k := k div 10000;
27 end;
28 end;
29
30 procedure work;
31 var
32 i, j, k: longint;
33 begin
34 for i := m+2 to m+n do
35 begin
36 j := 0;
37 k := i;
38 while k > 1 do
39 begin
40 inc(j);
41 while k mod su[j] = 0 do
42 begin
43 inc(d[j]);
44 k := k div su[j];
45 end;
46 end;
47 end;
48 k := m+1-n;
49 j := 0;
50 while k > 1 do
51 begin
52 inc(j);
53 while k mod su[j] = 0 do
54 begin
55 inc(d[j]);
56 k := k div su[j];
57 end;
58 end;
59 //for i := 1 to tot do
60 //if d[i] <> 0 then writeln(su[i],'',d[i]);
61 for i := 2 to n do
62 begin
63 j := 0;
64 k := i;
65 while k > 1 do
66 begin
67 inc(j);
68 while k mod su[j] = 0 do
69 begin
70 dec(d[j]);
71 k := k div su[j];
72 end;
73 end;
74 end;
75 ans.len := 1;
76 ans.dat[1] := 1;
77 for i := 1 to tot do
78 while d[i] > 0 do
79 begin
80 cheng(ans,su[i]);
81 dec(d[i]);
82 end;
83 //cheng(ans,m+1-n);
84 write(ans.dat[ans.len]);
85 for i := ans.len-1 downto 1 do
86 begin
87 if ans.dat[i] < 10 then begin write('000',ans.dat[i]); continue; end;
88 if ans.dat[i] < 100 then begin write('00',ans.dat[i]); continue; end;
89 if ans.dat[i] < 1000 then begin write('0',ans.dat[i]); continue; end;
90 end;
91 end;
92
93 procedure make;
94 var
95 i, j: longint;
96 f: boolean;
97 begin
98 for i := 2 to m+n do
99 begin
100 f := true;
101 for j := 2 to i-1 do
102 if i mod j = 0 then
103 begin f := false; break; end;
104 if f then
105 begin inc(tot); su[tot] := i; end;
106 end;
107 end;
108
109 begin
110 assign(input,'d:\in.txt');reset(input);
111 assign(output,'d:\out.txt');rewrite(output);
112 readln(m,n);
113 make;
114 work;
115 close(input);
116 close(output);
117 end.