TZOJ--3560: Ordered Fractions (枚举)

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

题目来源

USACO

 

题目链接: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会出现多次,所以特判输出
	}
} 

  

 

原文地址:https://www.cnblogs.com/Anidlebrain/p/10081195.html