题解:P13027 [GCJ 2021 #1A] Prime Time
wudongcheng0223 · · 题解
一道有点思维的难度的题,但是想到了还是很好做的。
题目传送门
题意简述
把一些质数分成两组,使第一组的和等于第二组的积,一种分法的得分为第一组的和(也就是第二组的积),输出最大的得分。
暴力思路
爆搜这里就不讲了吧。
注意到数字全是质数,和质数有关的是什么?质因数分解!对于每一个数,都可以把它分解为若干个质数的积的形式,并且分解方法是唯一的。
于是我们就有了一个暴力思路:从大到小枚举得分,然后遍历卡牌,如果得分能整除当前的卡牌就除掉,最后判断得分能否除到
一个小优化
现在得分的范围太大了,范围足足从
办法是有的。由于质数最小是
得出这个结论,这道题就很好做了。被选到第二组数字的和不会超过
最后提醒大家两句话:
多测不清空,爆零两行泪。
十年 OI 一场空,不开 long long 见祖宗。
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll T,m,p[105],n[105];
int main(){
cin>>T;
for(ll t=1;t<=T;t++){
cin>>m;
ll sum=0,ans=0,cnt=0;
for(ll i=1;i<=m;++i){
cin>>p[i]>>n[i];
sum+=p[i]*n[i];//所有计算数字总和
}
for(ll i=sum;i>=max((ll)2,sum-499*60);i--){
ll x=i,f=0,sum1=0;
for(ll j=1;j<=m;++j)
for(int k=1;k<=n[j]&&x%p[j]==0;k++){
x/=p[j];//能除的全都除掉
sum1+=p[j];//计算第二组数字的和
}
if(x>1)continue;//得分不能除完就不是合法方案
if(sum-sum1==i){//这是合法的情况
ans=i;
break;
}
}
cout<<"Case #"<<t<<": "<<ans<<'\n';
}
return 0;
}