[Swust OJ 491]--分数的位置(简单版)

 

题目链接:http://acm.swust.edu.cn/problem/0491/

Time limit(ms): 1000        Memory limit(kb): 65535
 
Description
将所有的分母小于N的真分数(分子小于分母,数值小于1)从小到大排列出来后,例如当N=4时,所有的真分数有1/4,1/3,1/2,2/3,3/4。其中第三个真分数为1/2,其分子为1,分母为2。编一个程序,对给定的N,求出第M个真分数的值。
 
Input
测试数据有多组,每组测试数据有两行: 
第一行有一个数N(3<=N<=10^3),第二行为一个数字M(3<=M<=10^5)。
 
Output
输出文件中对应每组测试数据输出一行,该行为这个真分数.无空格,见Sample Output. 
 
Sample Input
4
3
5
2

Sample Output
1/2
1/4

 
输入数据保证输出合法.
Hint
SCPC_周伟
 
 
解题思路:这道题我的思路就是把所有的分子分母最大公约数为1的分数存贮起来(由于使用的两个for,并没有按大小来,需要排序),排序后输出对应的分数
     这里需要确定数组大小,就是在分母小于n的情况下的数字,这里运用全排列来考虑,最多1000*100*10个组合满足,然后就能愉快的ac了~~~~
     比价两个分数大小a/b<c/d满足关系式a*d<b*c~~~
 
 
看提交记录有学长0ms秒过的,应该是找到了递推公式(然而我并没有找到),先看看这个搓代码吧Orz~~~
代码如下:
 1 #include <iostream>

 2 #include <algorithm>

 3 #include <cstdio>

 4 #define maxn 1000010

 5 using namespace std;

 6 struct node{

 7     int x, y;

 8     bool operator<(const node &tmp)const{

 9         if (x != tmp.x)

10             return x*tmp.y < y*tmp.x;

11         return y > tmp.y;

12     }

13 }a[maxn];

14 int gcd(int a, int b){

15     return !b ? a : gcd(b, a%b);

16 }

17 int main(){

18     int n, m;

19     while (~scanf("%d%d", &n, &m)){

20         int pos = 0;

21         //i代表分母,j代表分子

22         for (int i = 1; i <= n; i++){

23             for (int j = 1; j < i; j++){

24                 if (i == 1 && j == 1)

25                     continue;

26                 if (gcd(j, i) == 1){

27                     a[pos].x = j;

28                     a[pos++].y = i;//  x/y

29                 }

30             }

31         }

32         sort(a, a + pos);

33         printf("%d/%d\n", a[m - 1].x, a[m - 1].y);

34     }

35     return 0;

36 }

37 

38 //排序也可以这么单独写,看个人习惯

39 /*int cmp(node a, node b){

40     if (a.x == b.x)

41         return a.y > b.y;

42     return a.x*b.y < a.y*b.x;

43 }*/
View Code

 

 

你可能感兴趣的:(简单)