ZOJ 2523 —— Number of People(数论,胡搞)

来源:互联网 发布:android java游戏引擎 编辑:程序博客网 时间:2024/05/17 07:27

题目:Number of People

题意:N个人平均分成若干组开party,而且D天一个循环(汗,这开到什么时候),一个循环里每天一组的人数必须不一样,现在给出D,求最小的满足题意的N。

如果知道N,其实D就是N的因子的个数,有多少个不同因子就可以有多少次不同的分组。

求因子数的话将N进行质因数分解,N = a1^p1 * a2^p2 * a3^p3 ...,a是质因子,然后因子数=(p1+1)*(p2+1)*(p3+1)*... 

虽然D<10000,但N可能很大,比如D=101,101是质数,所以没得分解,此时最小的N = 2^100,连longlong都爆,预处理这种方案是不可行的。

现在反过来知道D,要求N。按照上面的式子可以想到将D分解成若干个因子得到指数,再将质数分配给质因子就能得到N,但是具体怎么分解最优我就不知道了。。。

比如样例1是分解成最多的个数,而样例2却是分解少的,如果分解成2*2*2得到2^1 * 3^1 * 5^1 = 30,反而更大。

所以我只能采取暴力枚举方案的极端手段了(> < 智商不够了)。

由于每次分解到的因子数并不会太多,所以不用担心暴力的时间。

判断大小我是直接用double乘起来,虽然会丢失一定的精度,但是由于这种指数运算稍微有点不同结果差异挺大的,所以比较还是没什么问题的。

#include<cstdio>#include<cstring>#include<algorithm>#include<functional>#include<cmath>using namespace std;const int N = 10010;bool f[N];int p[N], a[N], b[N], c[N], n, m, k;double ans;void dfs(int x){    if(x==k){        int L = 0;        for(int i=0; i<k; i++){            if(c[i])    b[L++] = c[i]-1;        }        sort(b, b+L, greater<int>());        double cur = 1.0;        for(int i=0; i<L; i++){            cur *= pow(p[i]*1.0, b[i]);        }        if(cur<ans){            ans = cur;            n = L;            for(int i=0; i<n; i++)  a[i] = b[i];        }        return;    }    dfs(x+1);    for(int i=x+1; i<k; i++){        c[i] *= c[x];        int tmp = c[x];        c[x] = 0;        dfs(x+1);        c[x] = tmp;        c[i] /= tmp;    }}int main(){    m = 0;    memset(f,0,sizeof(f));    for(int i=2; i<N; i++){        if(!f[i]){            p[m++] = i;            for(int j=i<<1; j<N; j+=i) f[j]=1;        }    }    int d;    while(~scanf("%d", &d)){        k = 0;        for(int i=0; i<m && d>1; i++){            if(d%p[i]==0){                while(d%p[i]==0){                    d/=p[i];                    a[k++] = p[i];                }            }        }        sort(a, a+k, greater<int>());        ans = 1.0;        for(int i=0; i<k; i++){            c[i] = a[i];            a[i]--;            ans *= pow(p[i]*1.0, a[i]);        }        n = k;        dfs(0);        for(int i=0; i<n; i++){            if(i)   printf(" * ");            printf("%d^%d", p[i], a[i]);        }        puts("");    }    return 0;}


0 0
原创粉丝点击