题目描述
输入一个自然数 n,对于一个最简分数 a/b(分子和分母互质的分数),满足 1≤b≤n,0≤a/b≤1,请找出所有满足条件的分数。
这有一个例子,当 =5n=5 时,所有解为:
01,15,14,13,25,12,35,23,34,45,1110,51,41,31,52,21,53,32,43,54,11
给定一个自然数 n,请编程按分数值递增的顺序输出所有解。
注:
1、00 和任意自然数的最大公约数就是那个自然数。
2、互质指最大公约数等于1的两个自然数。
输入格式
单独的一行一个自然数 n
输出格式
每个分数单独占一行,按照大小次序排列
输入输出样例
输入 #1
5
输出 #1
0/1 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 1/1
说明/提示
【数据范围】
对于 100%100% 的数据,1≤n≤160。
USACO 2.1
翻译来自NOCOW
#include<bits/stdc++.h>
using namespace std;
const int N=165;
struct node{
int a,b;
};
node z[N*N];
int n,k=1;
int gcd(int n,int m){
int r=n%m;
while(r!=0){
n=m;
m=r;
r=n%m;
}
return m;
}
bool cmp(node c,node d){
return c.b*d.a<c.a*d.b;
}
int main(){
cin>>n;
z[1].b=0, z[1].a=1;
for(int i=1;i<=n-1;++i)
for(int j=n;j>=i+1;--j){
int c=gcd(i,j);
z[++k].b=i/c;
z[k].a=j/c;
}
z[++k].b=1, z[k].a=1;
sort(z+1,z+k+1,cmp);
printf("0/1\n");
for(int i=2;i<=k;++i){
if(z[i].a==z[i-1].a && z[i].b==z[i-1].b) continue;
printf("%d/%d\n",z[i].b,z[i].a);
}
return 0;
}