タイトル: 有理近似
問題の説明:
入出力フォーマット
入力形式:
入力ファイルの最初の行は 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/DUXS11/article/details/132045467