小马哥的超级盐水

Posted shuaihui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小马哥的超级盐水相关的知识,希望对你有一定的参考价值。

来呀

题意:给n杯盐水,每一杯水有a单位盐,b单位水。给你一个x和y,问有多少种方法能配成x比y的盐水。

因为n只有35,没法枚举全部情况,如果n只有一般大,那么我们可以枚举所有情况。

我们可以把n分为两部分,枚举一部分的所有情况,然后找是否能和另一部分构成解。

对于(a1,b1)和(a2,b2)这两个集合。

易得(a1+a2)/(b1+b2)=x/y。

化简得到(y*a1-x*b1)=(x*b2-y*a2)。所以枚举前面的然后找后面的就行了。

AC代码:

技术分享图片
#include <iostream>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
struct node{
    ll ai,bi;
}a[105];
ll b[1<<19];

int main()
{
    int t;cin>>t;
    while(t--)
    {
        ll n;
        ll x,y;cin>>n>>x>>y;
        for(int i=0;i<n;i++)
        {
            cin>>a[i].ai>>a[i].bi;
        }
        int p=0;
        ll n1=n/2;
        ll n2=n-n1;
        ll m1=(1<<n1);
        ll m2=(1<<n2);
        for(int i=0;i<(m2);i++)
        {
            ll sum=0;
            for(int j=0;j<n2;j++)
            {
                if((i>>j)&1)
                {
                    sum+=a[j+n1].bi*x-a[j+n1].ai*y;
                }
            }
            b[p++]=sum;    
            //cout<<ans-1<<endl;
        }        

        sort(b,b+p);
        ll ans=0;
        for(int i=0;i<m1;i++)
        {
            ll sum=0;
            for(int j=0;j<n1;j++)
            {
                if((i>>j)&1)
                {
                    sum+=a[j].ai*y-a[j].bi*x;
                }
            }
            ans+=upper_bound(b,b+p,sum)-lower_bound(b,b+p,sum);
        }        
        cout<<ans-1<<endl;        
    }
    
    return 0;
}
View Code

 

以上是关于小马哥的超级盐水的主要内容,如果未能解决你的问题,请参考以下文章

腾讯云助推“数字中国”落地,小马哥的底气从何而来?

小马哥四轴代码解读-I2C-mpu6050篇

超级有用的9个PHP代码片段

题解报告:hdu 1408 盐水的故事

淡盐水的功效

10个超级有用必须收藏的PHP代码样例