https://codingcompetitions.withgoogle.com/codejam/round/000000000043585d/00000000007543d8#problem
这题关键是要发现两组牌的数字总和只有5e17,那么枚举乘积那组的总和为i,prod=sum-i ,i总是很小的,因为2^60=1e18,所以prod中最多60个数字,那么i最大是60*499
然后我们知道sum-i唯一分解,我们就用着m个数字去尝试分解sum-i,如果最后能分解成1,然后幂次小于等于给出的幂次,且分解出来的数字总和等于i,那么就是可行的
所以复杂度就是60*499*m*log5e17 大概1e8左右是完全可以过的
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=510;
int m;ll ans,sum,tot;
int p[maxl];ll num[maxl],a[maxl];
inline void prework()
{
scanf("%d",&m);
for(int i=1;i<=m;i++)
scanf("%d%lld",&p[i],&num[i]);
}
inline void mainwork()
{
ans=0;sum=0;
for(int i=1;i<=m;i++)
sum+=p[i]*num[i];
for(ll i=1;i<=499*60 && i<sum;i++)
{
ll x=sum-i,tmp=0;bool flag=true;
for(int j=1;j<=m;j++)
{
a[j]=0;
while(x%p[j]==0)
a[j]++,x/=p[j];
if(a[j]>num[j])
flag=false;
tmp+=a[j]*p[j];
}
if(x!=1 || tmp!=i)
flag=false;
if(flag)
{
ans=sum-i;
return;
}
}
}
inline void print()
{
printf("%lld\n",ans);
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
prework();
mainwork();
printf("Case #%d: ",i);
print();
}
return 0;
}