题目链接: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 }*/
时间: 2024-10-29 19:05:55