【排序】【USACO2.1.2】順序的分數
阿新 • • 發佈:2019-01-01
【問題描述】
輸入自然數N,對於一個最簡分數 a/b(分子和分母互質的分數),滿足1 <= b <= N,0 <= a/b <= 1,請找出所有滿足條件的分數。
這有一個例子,當N=5時,所有解為:
0/1 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 1/1
給定一個自然數N,1<=n<=160,請程式設計按分數值遞增的順序輸出所有解。
提示:
①、0 和任意自然數的最大公約數就是那個自然數。
②、互質指最大公約數等於1的兩個自然數。
【輸入格式】
單獨的一行 一個自然數N(1..160)
【輸出格式】
每個分數單獨佔一行,按照大小次序排列 。
【輸入樣例】
5
【輸出樣例】
0/1
1/5
1/4
1/3
2/5
1/2
3/5
2/3
3/4
4/5
1/1
【資料範圍】
1 <= N <= 160
題目大意:輸入一個正整數n,要求所有滿足1 <= b <= N的最簡真分數。
演算法:列舉+排序+gcd;
由於要滿足題目所給的條件的正整數b有很多,但都在區間[1,n],故在[1,n]上列舉b,由0<=a/b<=1得到0<=a<=b,再用一重迴圈列舉a,每次列舉一個(a,b),都用gcd是否為1判斷a,b是否互質,如果互質就將a,b壓入陣列中,然後根據分數值大小排序。
小技巧:由於本題是分式型排序,為了減小誤差,可以比較分式兩邊交叉相乘的結果(注意比較過程中是否超出int範圍)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#define maxn 165
#define eps 0.0000001
using namespace std;
int n;
struct data
{
int a,b;
};
vector<data>A;
bool cmp(data a,data b)
{
return a.a*b.b<b.a*a.b;
}
int gcd(int a,int b)
{
return b==0? a:gcd(b,a%b);
}
int main()
{
//freopen("my.in","r",stdin);
//freopen("my.out","w",stdout);
scanf("%d",&n);
for(int b=1;b<=n;b++)
for(int a=0;a<=b;a++)
{
if(gcd(a,b)==1)
{
A.push_back((data){a,b});
}
}
sort(A.begin(),A.end(),cmp);
for(int k=0;k<A.size();k++)
printf("%d/%d\n",A[k].a,A[k].b);
return 0;
}