C++ 有理逼近

题目:有理逼近

问题描述:在这里插入图片描述

输入输出格式

输入格式:

输入文件的第一行为 P 、 N P、N PN,其中 P 、 N < 30000 P、N<30000 PN<30000

输出格式:

输出文件只有一行,格式为“ X / Y U / V X/Y U/V X/YU/V”,注意: X / Y X/Y X/Y U / V U/V U/V之间有一个空格,答案必须是既约的,也就是说分子、分母的最大公约数必须等于 1 1 1

输入输出样例

输入样例#1:

5 100

输出样例#1:

38/17 85/38

做题思路:

这题我用的是枚举,就是从1~m中枚举出比根号P大的最小的一个分数比根号P小的最大的一个分数

好了好了,直接看代码注释吧:

AC代码

#include<bits/stdc++.h>
using namespace std;
long double t,ma=-1,mi=0x7fffffff;//ma是比根号P小的最大的一个分数值,mi是比根号P大的最小的一个分
数值
//注意:mi在数据较大的数据时初值要设的大一些,作者就在这里卡了好久
int x,y,u,v,p,m,fm;
int main()
{
	cin>>p>>m;
	t=sqrt(p);//由题目要求根号P
	for(fm=1;fm<=m;fm++){//这个循环是枚举分母(fm)的
		int fz=int(t*fm);//这个是分子(fz)      
		//赋值int(t*fm)这个东西是因为:分数值要最接近结果(t)所以  fz(分子)/fm(分母)=t  
		//然后移项就可以得出 fz=int(t*fm)。
		if(fz>m) break;//如果分子超出题目范围就直接break

		if(fz*1.0/fm>ma){//这里求比根号P小的最大的一个分数值
			ma=fz*1.0/fm;//记录
			x=fz;//x,y以及后面的u,v是记录最终结果的
			y=fm;
		}
		if (fz>=m)//如果分子超出题目范围就直接break(同上)
			break;
		if((fz+1)*1.0/fm<mi){//这里求比根号P大的最小的一个分数值
			mi=(fz+1)*1.0/fm;
			u=fz+1;
			v=fm;
		}
		
	}
	cout<<x<<"/"<<y<<" "<<u<<"/"<<v;//最后输出就好啦
	return 0;
}

总结:

这题其实不难,而且还有很多其他的方法,主要是得要有思路!!!

如果大家没听懂可以看看这篇文章,我就是看这篇文章学会的:

https://blog.csdn.net/DUXS11/article/details/132045467

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值