[题目描述]
Ordered Fractions
顺序的分数
输入一个自然数N
请写一个程序来增序输出分母小于等于N的既约真分数
PROGRAM NAME: frac1
INPUT FORMAT
单独的一行 一个自然数N(1..160)
SAMPLE INPUT (file frac1.in)
5
OUTPUT FORMAT
每个分数单独占一行
SAMPLE OUTPUT (file frac1.out)
0/1
1/5
1/4
1/3
2/5
1/2
3/5
2/3
3/4
4/5
1/1
[解题思路]
数据小,自然O(N^2)的枚举,求下Gcd(a,b),判断是否互质,最后快排一下输出即可。
USACO的ANALYSIS 里面还有个霸气侧漏的O(N)递归算法,区区30行,情何以堪...
可以将0/1与1/1做为左右端点,递归出解,不用排序。 每次将区间均分成两份,和普通的线段树很像...
[Code]
枚举+快排:
{
ID: zane2951
PROG: frac1
LANG: PASCAL
}
program frac1;
var
x,y:array[0..200*200+11] of longint;
n,top,i,j:longint;
//-----------qs------------
procedure qs(s,t:longint);
var
i,j,cex,cey,tmp:longint;
begin
i:=s; j:=t; cex:=x[(i+j)>>1]; cey:=y[(i+j)>>1];
repeat
while (x[i]*cey)<(y[i]*cex) do inc(i);
while (x[j]*cey)>(y[j]*cex) do dec(j);
if i<=j then
begin
tmp:=x[i]; x[i]:=x[j]; x[j]:=tmp;
tmp:=y[i]; y[i]:=y[j]; y[j]:=tmp;
inc(i); dec(j);
end;
until i>j;
if s<j then qs(s,j); if i<t then qs(i,t);
end;
//----------gcd------------
function gcd(a,b:longint):longint;
begin
if b=0 then exit(a) else exit(gcd(b,a mod b));
end;
//----------main-----------
begin
assign(input,'frac1.in'); reset(input);
assign(output,'frac1.out'); rewrite(output);
readln(n);
top:=2;
x[1]:=0; y[1]:=1;
x[2]:=1; y[2]:=1;
for i:=2 to n do
for j:=1 to i-1 do
if (i and 1>0) or (j and 1>0) then
if gcd(i,j)=1 then
begin
inc(top);
x[top]:=j;
y[top]:=i;
end;
qs(1,top);
for i:=1 to top do writeln(x[i],'/',y[i]);
close(input); close(output);
end.
递归:
{
ID: zane2951
PROG: frac1
LANG: PASCAL
}
program frac1;
var
n:longint;
//----------run------------
procedure run(x1,y1,x2,y2:longint);
begin
if y1+y2>n then exit;
run(x1,y1,x1+x2,y1+y2);
writeln(x1+x2,'/',y1+y2);
run(x1+x2,y1+y2,x2,y2);
end;
//----------main-----------
begin
assign(input,'frac1.in'); reset(input);
assign(output,'frac1.out'); rewrite(output);
readln(n);
writeln('0/1');
run(0,1,1,1);
writeln('1/1');
close(input); close(output);
end.