题目描述
输入一个自然数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)
输出格式:
每个分数单独占一行,按照大小次序排列
输入输出样例
说明
USACO 2.1
翻译来自NOCOW
哇,
好像是个搜索题,
好久没写搜索了,,
怎么写???
枚举好像也可以诶~
最开始的0/1和最后面的1/1是固定的,
而且其他的什么0/2,0/3……0/n啊
2/2,3/3,……n/n啊都是相等的,所以都不要。
那这两个就单独处理,
其他的,循环,判断,枚举。
用结构体是比较简单的做法。
定义一个结构体表示分子分母和分数值。
按照分数值由小到大排序,
然后写一个判断函数,
判断分子和分母是否互质(gcd==1)。
然后就循环枚举了,
只保留分子小于分母的情况,
排序,判断,取舍,输出。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<queue> 7 using namespace std; 8 9 int n,sum; 10 11 struct node{ 12 int x,y; //分子和分母 13 double z; //分数值 14 }a[168*168]; //开大一点,不然会re 15 16 int gcd(int x,int y) 17 { 18 return !x?y:gcd(y%x,x); //求最大公约数,记住。 19 } 20 21 bool judge(int x,int y) //判断分子和分母的 22 { 23 if(gcd(x,y)==1) return 1; //最大公约数是否为一。 24 else return 0; 25 } 26 27 bool cmp(node x,node y) //按照分数值大小排序。 28 { 29 return x.z <y.z ; 30 } 31 32 int main() 33 { 34 scanf("%d",&n); 35 printf("0/1 "); 36 for(int i=1;i<=n;++i) 37 for(int j=n;j>=1;--j) 38 if(i<j) //枚举保留可行解 39 { 40 sum++; 41 a[sum].x =i; 42 a[sum].y =j; 43 a[sum].z =(1.0*i)/(1.0*j)*1.0; 44 } 45 sort(a+1,a+sum+1,cmp); 46 for(int i=1;i<=sum;++i) 47 if(judge(a[i].x ,a[i].y )) //舍去一些不合法的。 48 printf("%d/%d ",a[i].x ,a[i].y ); 49 printf("1/1"); 50 return 0; 51 }
如果你不开心,那我就把右边这个帅傻子分享给你吧,
你看,他这么好看,那么深情的望着你,你还伤心吗?
真的!这照片盯上他五秒钟就想笑了。
一切都会过去的。