紫上给得比较奇怪,其实没有必要用唯一分解定理。我觉得这道题用唯一分解只是为了表示大数。
但是分解得到的幂,累乘的时候如果顺序很奇怪也可能溢出。其实直接边乘边除就好了。因为答案保证不会溢出,
设定一个精度范围,如果中间结果超过了精度范围就保存起来,最后sort一遍从两端同时乘就不会溢出了。
/********************************************************* * --------------Tyrannosaurus--------- * * author AbyssalFish * **********************************************************/ /* 数的表示,唯一表示,固定进制,变进制(编码),素因子幂 不唯一表示 很多 */ #include<bits/stdc++.h> using namespace std; const int maxn = 1e4+1; vector<double> ans_fac; const double up_b = 1e8, low_b = 1e-8; //#define LOCAL int main() { #ifdef LOCAL freopen("in.txt","r",stdin); #endif int p, q, r, s; while(~scanf("%d%d%d%d", &p, &q, &r, &s)){ int m = max(p, r), x = p-q, y = r-s; double ans = 1; for(int i = 2; i <= m; i++){ int t = 0; if(q < i && i <= p) t++; if(i <= x) t--; if(s < i && i <= r) t--; if(i <= y) t++; if(t){ if(t < 0) while(ans /= i, ++t) ; else do ans *= i; while( --t) ; if(ans > up_b || ans < low_b) { ans_fac.push_back(ans); ans = 1; } } } if(ans_fac.size()){ sort(ans_fac.begin(),ans_fac.end()); int i = 0, j = ans_fac.size()-1; while(i < j){ ans *= ans_fac[i++]*ans_fac[j--]; } if(i == j) ans *= ans_fac[i]; ans_fac.clear(); } printf("%.5lf\n", ans); } return 0; }
时间: 2024-12-24 15:13:35