C++ 有理近似

タイトル: 有理近似

問題の説明:ここに画像の説明を挿入

入出力フォーマット

入力形式:

入力ファイルの最初の行は P, N です。P, N<30000 です。

出力フォーマット:

出力ファイルは 1 行のみで、形式は「X/YU/V」です。注: X/Y と U/V の間にはスペースがあり、答えは近似値、つまり次の最大公約数である必要があります。分子と分母は 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/DUXS​​11/article/details/132045467

おすすめ

転載: blog.csdn.net/m0_61360607/article/details/132063565