AcWing 1360. 有序分数(每日一题)

简介: AcWing 1360. 有序分数(每日一题)

原题链接:1360. 有序分数 - AcWing题库

题目:

给定一个整数 N,请你求出所有分母小于或等于 N,大小在 [0,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。

输出格式

按照从小到大的顺序,输出所有满足条件的分数。

每个分数占一行,格式为 a/b,其中 a 为分子, b为分母。

数据范围

1≤N≤160

输入样例:

5

输出样例:

0/1
1/5
1/4
1/3
2/5
1/2
3/5
2/3
3/4
4/5
1/1
枚举版:

由于此题数据量很小只有160,O(N^2)解决此问题完全没问题,具体思路外循环枚举分母,内循环枚举分子。只要没有最大公约数,就存取下来,然后针对于分数进行排序输出即是答案。分数排序如下图:

#include<iostream>
#include<algorithm>
using namespace std;
int n;
typedef pair<int,int> PII;
PII p[50000];//至少要开到N*N
int gcd(int a,int b){//最大公约数
  return b?gcd(b,a%b):a;
}
int cmp(PII a,PII b){//a.second/a.first<b.second/b.first,分母同时同分就得到下面式子
  return a.first*b.second>b.first*a.second;
}
int main(){
  cin>>n;
  int k=0;
  for(int i=0;i<=n;i++){
    for(int j=0;j<=i;j++){
      if(gcd(i,j)==1){//只要没有最大公约数就往里面放
        p[k++]={i,j};
      }
    }
  }
  sort(p,p+k,cmp);//由小到大排序
  for(int i=0;i<k;i++){//second是分子,first是分母
    cout<<p[i].second<<"/"<<p[i].first<<endl;
  }
  return 0;
}
递归版(Stern-Brocot Tree):

Stern-Brocot Tree:

Stern-Brocot Tree主要思想就是不断递归分裂,对于本题而言,就是第二张图,开始[0/1,1/1],找到mid=0+1/1+1,区间分裂[0/1,1/2]与[1/2,1/1],[0/1,1/2]再分裂mid=0+1/1+2,区间分裂为[0/1,1/3]与[1/3,1/2],[1/2,1/1]再分裂mid=1+1/1+2,

区间分裂为[1/2,2/3]与[2/3,1/1],以此类推……这样就得到了答案,用一个递归函数,不断往下找即可。

#include<iostream>
using namespace std;
int n;
//递归做法
void dfs(int a,int b,int c,int d){//a第一个数分母,b第一个数分子,c第二个数分母,d第二个数分子
  if(a+c>n)return;//如果分母之和大于n了就返回
  dfs(a,b,a+c,b+d);//左区间[b/a,b+d/a+c]
  cout<<b+d<<"/"<<a+c<<endl;//中间数b+d/a+c
  dfs(a+c,b+d,c,d);//右区间[b+d/a+c,d/c]
}
int main(){
  cin>>n;
  cout<<"0/1"<<endl;//第一个数0单独输出
  dfs(1,0,1,1);//从[0/1,1/1]开始
  cout<<"1/1"<<endl;//最后一个数单独输出
  return 0;
}
总结:

在做此题时,很容易想到第一种方法,第二种Stern-Brocot Tree第一次了解,顺便学习一下,在算法思想上比较简单了,也比较容易理解。大家都可以学习一下,虽然运行效率差不多,但是使用Stern-Brocot Tree的代码很简单。冲刺蓝桥杯路上会遇到各种各样的方法,大家选择自己擅长的即可,只要能ac题目的算法都是好算法。博主水平有限,文章写的一般,在描述上可能不是很清楚,若有不明白的地方,可评论,看到必回复。若文章有错误的地方,请大家指出,纠正错误,规范自己,大家一起加油。


相关文章
|
5月前
|
算法
力扣每日一题 6/16 字符串 + 随机一题 动态规划/数学
力扣每日一题 6/16 字符串 + 随机一题 动态规划/数学
43 0
|
6月前
|
机器学习/深度学习 算法
刷题记录:牛客-WY49数对 | 以数学分析来破解暴力搜索的时间复杂度问题 2023/1/11
这是一个关于编程题解的文章摘要,讨论了一道名为&quot;WY49 数对&quot;的问题。文章指出,暴力搜索的解决方案在大规模问题中效率低下,然后转向通过数学分析来寻找更优解。作者解释了如何根据除数和余数的关系,以及余数的周期性变化来计算满足条件的数对数量。通过将数对中的其中一个数(被模数x)按除数y划分区间,并分析每个区间的余数分布,得出一个公式来计算总数。最后,提供了两种不同的代码实现来展示这个思路,这些代码具有O(n)的时间复杂度和O(1)的空间复杂度。文章强调了理解数学方法在解决此类问题中的重要性,特别是对于优化算法性能的作用。
89 3
|
5月前
|
算法
【经典LeetCode算法题目专栏分类】【第6期】二分查找系列:x的平方根、有效完全平方数、搜索二位矩阵、寻找旋转排序数组最小值
【经典LeetCode算法题目专栏分类】【第6期】二分查找系列:x的平方根、有效完全平方数、搜索二位矩阵、寻找旋转排序数组最小值
|
6月前
|
算法
代码随想录算法训练营第五十六天 | LeetCode 647. 回文子串、516. 最长回文子序列、动态规划总结
代码随想录算法训练营第五十六天 | LeetCode 647. 回文子串、516. 最长回文子序列、动态规划总结
55 1
|
算法 Android开发
LeetCode 周赛上分之旅 #38 结合排序不等式的动态规划
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
80 0
【LeetCode-每日一题】-16. 最接近的三数之和
【LeetCode-每日一题】-16. 最接近的三数之和
|
6月前
|
算法
六六力扣刷题数组之有序数组的平方
六六力扣刷题数组之有序数组的平方
45 0
|
机器人 Java Python
leetcode每日一题.200:岛屿数量
leetcode每日一题.200:岛屿数量
79 0
|
人工智能 算法 搜索推荐
LeetCode 周赛 338,贪心 / 埃氏筛 / 欧氏线性筛 / 前缀和 / 二分查找 / 拓扑排序
大家好,我是小彭。 上周末是 LeetCode 第 338 场周赛,你参加了吗?这场周赛覆盖的知识点很多,第四题称得上是近期几场周赛的天花板。
109 0