Q1(hdu6209):優化
給出常數k,欲用相似二分搜索的迭代策略,求解方程k^2=x^3分母不超過100000的最近似的解的最簡分數形式。spa
分析:這是一個很直觀方程求數值解的數值分析問題,所以應該可以聯想到的是用迭代搜索策略。這裏有以下兩種策略:code
策略1(二分迭代):可行解在[a/b , c/d]中,下次迭代考慮重點(ad+bc)/2cd.blog
策略2(類二分策略):可行解在[a/b , c/d]中,下次迭代考慮(a+c)/(b+d).io
考慮這裏用策略而可以保證整個迭代過程當中,分數的分子和分母必定是互素的,這也會爲迭代的效率上帶來優化。參考代碼以下:class
#include<cstdio> using namespace std; typedef long long LL; typedef long double LD; const LD INF = 1e60; LD Abs(LD x){ return x > 0 ? x : -x; } int main(){ int T; LL L_son , L_mom ,R_son , R_mom , M_son , M_mom , ans_son , ans_mom; LD deta; LL K , x , aim; scanf("%d" , &T); while(T--){ scanf("%lld" , &K); aim = K * K; x = 1; while(x*x*x < aim) x++; if(x*x*x == aim){ printf("%lld/1\n" , x); continue; } else{ //分佈在[x-1 , x]之中,x - 1是解的整數部分 L_son = x - 1; L_mom = 1; R_son = x; R_mom = 1; } deta = INF; while(1){ M_son = L_son + R_son; M_mom = L_mom + R_mom; if(M_mom > 100000) break; LD u = M_son; LD v = M_mom; LD temp = u*u*u/v/v/v; if(Abs(temp - aim) < deta){//維護最小距離 ans_son = M_son; ans_mom = M_mom; deta = Abs(temp - aim); } if(temp < aim){ //削減迭代區間 L_son = M_son; L_mom = M_mom; } else{ R_son = M_son; R_mom = M_mom; } } printf("%lld/%lld\n" , ans_son , ans_mom); } return 0; }