您的位置:首页 > 其它

2010 Asia Regional Hangzhou Site —— Online Contest

2012-09-05 16:06 309 查看
【题目链接】

HDU3641 Treasure Hunting

  对ai进行质因子分解,然后在long long范围内二分找出题目所求最小x。

  通过这道题学到了快速求阶乘包含某个因子的个数,下面是简要证明:

出处:/article/5245353.html

  给定两个数m,n

  求m!分解质因数后因子n的个数。

  这道题涉及到了大数问题,如果相乘直接求的话会超出数据类型的范围。

  下面给出一种效率比较高的算法,我们一步一步来。

  m!=1*2*3*……*(m-2)*(m-1)*m

  可以表示成所有和n倍数有关的乘积再乘以其他和n没有关系的

   =(n*2n*3n*......*kn)*other other是不含n因子的数的乘积 因为 kn<=m 而k肯定是最大值 所以k=m/n

   =n^k*(1*2*......*k)*other

  =n^k*k!*other     

  从这个表达式中可以提取出k个n,然后按照相同的方法循环下去可以求出k!中因子n的个数。

  每次求出n的个数的和就是m!中因子n的总个数。

View Code

#include <stdio.h>
#include <string.h>
#include <algorithm>
struct expo
{
int s, t;
}e[101];

bool flag[101];
int a;

bool cmp(expo a, expo b)
{
return a.s == b.s ? (a.t < b.t ? 1 : 0): a.s < b.s ;
}

bool check(int n)
{
int i;
for(i = 0 ; i < n; i ++)
if(!flag[i])
break;
if(i == n)
return true;
a = e[i].t;
flag[i] = true;
return false;
}

int main()
{
int n, i, cnt;
while(scanf("%d", &n), n)
{
memset(flag, false, sizeof(flag));
for(i = 0; i < n;i ++)
scanf("%d%d", &e[i].s, &e[i].t);
std::sort(e, e + n, cmp);
cnt = 0;
while(!check(n))
{
cnt ++;
for(i = 1; i < n; i ++)
if(!flag[i] && e[i].s > a)
flag[i] = true, a = e[i].t;
}
printf("%d\n", cnt);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐