加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

POJ PKU 2613 模拟

(2010-04-29 15:14:45)
标签:

poj

pku

2613

it

分类: 杂题

 题目描述:

compute the the result of dividing C(p,q) by C(r,s)

解题报告:

所有的数字都可以分解成素数的乘积,所以最后分子和分母可以拆分成最简的几个素数。

卡精度,从分子的项开始乘,大于100000000时,除分母的项,直到小于100000000。

代码如下:

#include<iostream>
#include<cmath>
#include <iomanip>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
#define size 1230
#define mmax 50000
#define maxn 10000
#define maxp 10000
int ud[2][size], p, q, r, s, x[10004][size], cnt1, cnt2;
char mk[maxn];
double up[mmax], down[mmax];
int prime[maxp], pnum;
void Prime(int n)
{
    int i, j, k;pnum = 0;memset(mk, 0, n 1);
    for(i = 2, k = 4; i <= n; i , k = i i - 1)
        if (!mk[i])
        {
            prime[pnum ] = i;
            if (k <= n)
                for(j = i i; j <= n; j = i)
                    mk[j] = 1;
        }
}
void judge(int pos)
{
    int y = pos;
    for(int i = 0; y != 1; i )
        while(y % prime[i] == 0)
        {
            x[pos][i] ;
            y /= prime[i];
        }
}
void jeogia(int n)
{
    for(int i = 2; i <= n; i )
    {
        for(int j = 0; j < size; j )
            x[i][j] = x[i - 1][j];
        judge(i);
    }
}
void merge(int a, int b, int c, int pos)
{
    for(int i = 0; i < size; i )
        ud[pos][i] = x[a][i] x[b][i] x[c][i];
}
void minu()
{
    cnt1 = cnt2 = 0;
    for(int i = 0; i < size; i )
    {
        if (ud[0][i] < ud[1][i])
        {
            ud[1][i] -= ud[0][i];
            ud[0][i] = 0;
            for(int j = 0; j < ud[1][i]; j )
                down[cnt2 ] = prime[i];
        }
        else
        {
            ud[0][i] -= ud[1][i];
            ud[1][i] = 0;
            for(int j = 0; j < ud[0][i]; j )
                up[cnt1 ] = prime[i];
        }
    }
}
int main()
{
    Prime(10000);
    memset(x, 0, sizeof(x));
    jeogia(10000);
    while(scanf("%d%d%d%d", &p, &q, &r, &s) != EOF)
    {
        memset(ud, 0, sizeof(ud));
        merge(p, s, (r - s), 0);
        merge(r, q, (p - q), 1);
        minu();
        double ans = 1;
        sort(up, up cnt1);
        sort(down, down cnt2);
        int j = cnt2 - 1;
        for(int i = cnt1 - 1; i >= 0; i--)
        {
            ans *= up[i];
            while(ans >= 100000000 && j != -1)
                ans /= down[j--];
        }
        while(j != -1)
            ans /= down[j--];
        printf("%.5f\n", ans);
    }
    return 0;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有