3560: Ordered Fractions
描述
Consider the set of all reduced fractions between 0 and 1 inclusive with denominators less than or equal to N.
Here is the set when N = 5:
0/1 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 1/1
Write a program that, given an integer N between 1 and 160 inclusive, prints the fractions in order of increasing magnitude.
输入
One line with a single integer N.
输出
One fraction per line, sorted in order of magnitude.
样例输入
5
样例输出
0/1
1/5
1/4
1/3
2/5
1/2
3/5
2/3
3/4
4/5
1/1
题目来源
题目链接:http://tzcoder.cn/acmhome/problemdetail.do?&method=showdetail&id=3560
题目大意:输出所有分母小于N,且分数值在0-1之间的所有分数
两重循环枚举以0-n为分子,1-n为分母的所有分数,然后去除重复的排序输出
我们可以考虑优化一下这个暴力,我们发现重复的 1/2 = 2/4 = 3/6,后面这些重复的都不是最简分数,所以我们只需要存在所有的最简分数,这样就不需要去重。
优化前:
#include<iostream> #include<algorithm> #include<string.h> using namespace std; struct A { int z;//分子 int m;//分母 double a;//分数的值,因为数字很小,可以直接double比较是否相等 }; int gcd(int x, int y) { if (x % y) return gcd(y , x % y); return y; } bool cmp(A x,A y) //按照 分数的值 进行排序从小到大输出 { return x.a<y.a; } A symp[12882],temp; int main(void) { int n,i,j,j_m,i_z,g,x; scanf("%d",&n); x=1; symp[0].a=0; for(j=1; j<=n; j++){ for(i=1; i<=j; i++){//分子大于分母就大于1,可以不用遍历枚举 g=gcd(j,i); j_m=j/g; i_z=i/g; symp[x].a=i_z*1.0/j_m; symp[x].z=i_z; symp[x].m=j_m; x++; } } sort(symp,symp+x,cmp); cout<<"0/1"<<endl; for(i=1; i<x; i++) { if(symp[i].a==symp[i-1].a) continue;//和前一项相等的,表示重复了,可以不用输出 else printf("%d/%d ",symp[i].z,symp[i].m); } return 0; }
优化后的代码:(我队友写的)
#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; struct shu { int fenzi; int fenmu; }a[165*165]; int gcd(int x,int y) { return y==0?x:gcd(y,x%y); } bool cmp(shu x,shu y)//分数通分后比较分子 { int z=gcd(x.fenmu,y.fenmu); z=x.fenmu*y.fenmu/z; return x.fenzi*(z/x.fenmu)<y.fenzi*(z/y.fenmu); } int main() { int i,j,n,k; while(~scanf("%d",&n)) { k=0; for(i=2;i<=n;i++) { for(j=1;j<i;j++) { if(gcd(i,j)!=1)continue;//判断是否是最简分数 a[k].fenzi=j; a[k++].fenmu=i; } } sort(a,a+k,cmp); printf("0/1 "); for(i=0;i<k;i++) { printf("%d/%d ",a[i].fenzi,a[i].fenmu); } printf("1/1 ");// 1/1 的gcd等于1会出现多次,所以特判输出 } }