UVA 10375 Choose and divide(大数的表示)

紫上给得比较奇怪,其实没有必要用唯一分解定理。我觉得这道题用唯一分解只是为了表示大数。

但是分解得到的幂,累乘的时候如果顺序很奇怪也可能溢出。其实直接边乘边除就好了。因为答案保证不会溢出,

设定一个精度范围,如果中间结果超过了精度范围就保存起来,最后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;
}

 

posted @ 2015-11-11 23:56  陈瑞宇  阅读(238)  评论(0编辑  收藏  举报