写在前面

  • 思路分析
  • 最大公约数函数
  • 计算结果左右边界​​int left = 0, right = 0;​
  • 左边界向上取整,右边界向下取整
  • 左右边界不包含
  • 区间迭代,最大公约数为1,打印当前分数结果
  • 自动有序
  • 测试点
  • ​2个不相等的正分数非正序输出!​
  • 左右边界问题,导致测试点2、3、4错误
  • 左右边界不包含
if(n1*1.0/m1<n2*1.0/m2)
{
left = n1*k/m1+1;
right = n2*k%m2==0 ? n2*k/m2-1 : n2*k/m2;
}
else
{
left = n2*k/m2+1;
right = n1*k%m1==0 ? n1*k/m1-1 : n1*k/m1;
}
  • 题目简单,10分钟a题
  • 细节处理尤为重要!
  • 复杂实现,简直不能忍
  • 一堆同质软文代码,无解释简直不能忍,,,

测试用例

input:
7/18 13/20 12
output:
5/12 7/12

intput:
3/12 7/12 12
output:
5/12

ac代码

#include <iostream>
using namespace std;
int gcd(int a, int b)
{
return b==0? a: gcd(b,a%b);
}
int main()
{
int n1, m1, n2, m2, k;
scanf("%d/%d %d/%d %d", &n1,&m1,&n2,&m2,&k);

/* 搞错1个条件 right计算向下取整(18分) */
int left = 0, right = 0;
if(n1*1.0/m1<n2*1.0/m2)
{
left = n1*k/m1+1;
right = n2*k%m2==0 ? n2*k/m2-1 : n2*k/m2;
}
else
{
left = n2*k/m2+1;
right = n1*k%m1==0 ? n1*k/m1-1 : n1*k/m1;
}

bool flag = false;
for(int i=left; i<=right; i++)
{
if(gcd(k,i)!=1)
continue;
printf("%s%d/%d", flag==true? " ":"", i, k);
if(!flag)
flag = true;
}
return 0;
}

学习代码

  • 思路分析
  • 辗转相除法gcd计算a和b的最大公约数
  • 调换n1和n2、m1和m2的位置
  • 令num=1,当n1 * k >= m1 * num时,num不断++,直到num符合n1/m1 < num/k为止
  • gcd(num, k)是否等于1判断num和k是否有最大公约数,等于1表示没有最大公约数,输出num/k,
  • num不断++直到退出循环
#include <iostream>
using namespace std;
int gcd(int a, int b){
return b == 0 ? a : gcd(b, a % b);
}
int main() {
int n1, m1, n2, m2, k;
scanf("%d/%d %d/%d %d", &n1, &m1, &n2, &m2, &k);
if(n1 * m2 > n2 * m1) {
swap(n1, n2);
swap(m1, m2);
}
int num = 1;
bool flag = false;
while(n1 * k >= m1 * num) num++;
while(n1 * k < m1 * num && m2 * num < n2 * k) {
if(gcd(num, k) == 1) {
printf("%s%d/%d", flag == true ? " " : "", num, k);
flag = true;
}
num++;
}
return 0;
}

知识点小结

// 数值交换
swap(a, b);

// 最大公约数
int gcd(int a, int b)
{
return b==0? a: gcd(b,a%b);
}