有数学符号图片,复制不过来,所以只能附上原题地址
题目地址:http://acm.zju.edu.cn/onlinejudge/showContestProblem.do?problemId=5970
题意:给出了三个新定义
- E-prime : ∀ num ∈ E,不存在两个偶数a,b,使得 num=a*b;(简言之,num的一对因子不能全为偶数)
- E-prime factorization : 定义集合P由 E-prime 元素组成,定义 e = p1*p2*.....*pn;(p1,p2,....,pn ∈ P , |P| = n)
- E-factorial : 定义 e!! = 2*4*6*8*.........*e;(简言之,偶数e及其之前的偶数连乘积)
输出一个数 e ,求满足条件2的集合P,并且集合P需满足:p1*p2*.....*pn = e!! , |P| = n;
求 n 的最大值;
题解:
别看定义了一堆东西,实际上就是给你一个偶数,先算出他的偶阶乘(比如给你一个12,偶阶乘就是2×4×6×8×10×12)
然后求出这个阶乘最多可以由多少个偶数相乘得到
因为这个阶乘是用偶数乘起来的,想要个数最多,肯定是用2乘,所有就求一下一共含有多少2就可以了,奇数可以不考虑
因为如果有奇数,那就用2乘上它让它变成偶数就ok了
因为输入的数据非常大,题目范围是1e10000,所以要用大数字处理。
反思:
写的时候题目没完全理解,想成求多少个因子为“2”,其实方向对了,可是做法却一直推规律,结果最后也没搞定,大佬一句1e10000就是2的3000多次方就点出题解了,可是自己还没想到,真的菜
代码:
python
t = int(input())
while t > 0:
n = int(input())
ans = int(0)
t -= 1
while n > 0:
n //= 2
ans += n
print(ans)
java大数
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t;
t = sc.nextInt();
while(t -- > 0){
BigInteger n = null;
n = sc.nextBigInteger();
BigInteger x = new BigInteger("2");
BigInteger p = new BigInteger("0");
BigInteger sum = new BigInteger("0");
while(n.compareTo(p) != 0)
{
sum = sum.add(n.divide(x));
n = n.divide(x);
}
System.out.println(sum);
}
}
}
c++
#include<iostream>
#include<cstdio>
using namespace std;
#define BigInteger long long
BigInteger e;
BigInteger base;
BigInteger F()
{
BigInteger curBase=2;
BigInteger ans=0;
BigInteger l=base/curBase;
BigInteger r=e/curBase;
for(int i=1;i < 4000;++i)
{
// cout<<l<<' '<<r<<endl;
if(l >= r)
break;
BigInteger tmp=(r-l)/2;
if(r&1)
tmp++;
ans=ans+tmp*i;
l=l/2;
r=r/2;
}
return ans;
}
void Solve()
{
base=1;
while(base*2 <= e)
base *= 2;
BigInteger ans=base-1;
if(base != e)
ans=ans+F();
cout<<ans<<endl;
}
int main()
{
int test;
while(cin>>test)
{
while(test--)
{
cin>>e;
Solve();
}
}
return 0;
}