3 选择与除法 UVa10375

1.题目描述:点击打开链接

2.解题思路:本题让计算两个组合数的商,,既可以直接利用公式,也可以利用唯一分解定理:事先计算10000以内的所有素数,然后计算组合数分解后各个素数的幂,用数组e保存指数即可。这里计算指数时可以利用数论中求n!分解式中各个素因数指数的公式。

3.代码:

(利用唯一分解定理)

#define _CRT_SECURE_NO_WARNINGS #include<iostream>#include<algorithm>#include<string>#include<sstream>#include<set>#include<vector>#include<stack>#include<map>#include<queue>#include<deque>#include<cstdlib>#include<cstdio>#include<cstring>#include<cmath>#include<ctime>#include<functional>using namespace std;#define maxn 10000+10int vis[maxn];int e[maxn];vector<int>primes;void init()//计算10000以内的素数{int m = sqrt(maxn + 0.5);for (int i = 2; i <= m; i++)if (!vis[i])for (int j = i*i; j <= 10000; j += i)vis[j] = 1;for (int i = 2; i <= 10000; i++)if (!vis[i])primes.push_back(i);}void add_factorial(int n, int d)//计算指数并添加到数组e{int tmp = n;for (int i = 0; i < primes.size(); i++){if (n / primes[i] == 0)break;int sum = 0;int x = primes[i];while (n / x>0){sum += n / x;x = x*primes[i];}if (d == 1)e[i] += sum;elsee[i] -= sum;}}int main(){//freopen("test.txt", "r", stdin);int p, q, r, s;init();while (cin >> p >> q >> r >> s){memset(e, 0, sizeof(e));add_factorial(p, 1);add_factorial(q, -1);add_factorial(p – q, -1);add_factorial(r, -1);add_factorial(s, 1);add_factorial(r – s, 1);double ans = 1;for (int i = 0; i < primes.size(); i++)ans *= pow(primes[i] , e[i]);printf("%.5lf\n", ans);}return 0;}

(利用公式直接计算)

#include <cstdio>#include <algorithm>using namespace std;int main () {int p, q, r, s;while (scanf ("%d%d%d%d", &p, &q, &r, &s) != EOF) {q = min (q, p – q);s = min (s, r – s);double ans = 1.0;for (int i = 1; i <= q || i <= s; i++) {if (i <= q)ans = ans * (p – i + 1) / i;if (i <= s)ans = ans * i / (r – i + 1);}printf ("%.5lf\n", ans);}return 0;}

当世界给草籽重压时,它总会用自己的方法破土而出。

3 选择与除法 UVa10375

相关文章:

你感兴趣的文章:

标签云: