ZOJ 2523 —— Number of People(数论,胡搞)
2014-08-17 11:10
197 查看
题目: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乘起来,虽然会丢失一定的精度,但是由于这种指数运算稍微有点不同结果差异挺大的,所以比较还是没什么问题的。
题意: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 ; int p , a , b , c , 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; }
相关文章推荐
- TOJ 2909 ZOJ 3175 Number of Containers / 数论
- zoj 3175 Number of Containers(数论~)
- codeforces 27E - Number With The Given Amount Of Divisors (数论 dfs)
- ZOJ 3175 Number of Containers 【数学图像性质(一个常见算式的经典计算)】
- ZOJ 3449 Doraemon's Number Game III (数论)
- ZOJ - 3175 Number of Containers
- ACM 数论 hdu 1492 The number of divisors(约数) about Humble Numbers
- hdoj 1492 The number of divisors(约数) about Humble Numbers 【数论】【质因子分解 求和】
- Find minimum number of people to reach to spread a message across all people in twitter
- codeforces 27E E. Number With The Given Amount Of Divisors(dp+数论)
- HDU 1492 The number of divisors(约数) about Humble Numbers(数论题目要知道定理呀....)
- Number of Containers [ZOJ 3126]
- zoj 3175 Number of Containers 分块加速
- [zoj 3774]Power of Fibonacci 数论(二次剩余 拓展欧几里得 等比数列求和)
- [zoj 3774]Power of Fibonacci 数论(二次剩余 拓展欧几里得 等比数列求和)
- Ccodeforces 27E Number With The Given Amount Of Divisors(数论+搜索)
- ZOJ 1484 Minimum Inversion Number(线段树,数论)
- zoj 3175 Number of Containers (nbut1375) 计算n /1+n/2+n/3+n/4....+n/n
- zoj 3175 Number of Containers (大数灵活题,除2改成平方根)
- [CodeForces 27E] Number With The Given Amount Of Divisors (数论 + 反素数)