您的位置:首页 > 其它

L - Basketball Gym - 100741L---e二进制枚举

2017-08-23 14:09 288 查看
题意:

输入n,m。分别代表每个队人数,然后下面两行,第一行n个数,每个数字代表每个人能力值,第二行m个数,每个数字代表每个人能力值。求从n中选几个人,m中选几个人,能力值之和相等(即:两队势力平衡)的方法有多少种,注意:两队所选的人多数可以不同,只要能量值和相能就可以。

思路:

二进制枚举,把每种情况列举出来,然后看两个队和相等的情况有多少种,方法就有多少种。

第一遍的代码(超时):  将两个组的所有自己子集情况分别存到两个数组里。然后比照和相等的情况,然而超时了。

#include <iostream>

#include <iomanip>

#include <cstring>

#include <cstdio>

#include <map>

using namespace std;

int ans; int k=0,l=0;

int N[18],M[18];

int aa[18],bb[18];

void subset(int n,int s,int chose,int *a)

{

    long long int tmp=0;

    for(int i=0;i<n;i++)

    {

        if(s&(1<<i))//如果两个位置上都是1则为真

       // printf("%d ",i);

          tmp+=a[i];

    }

    if(chose==1)

    {

       if(tmp)

      aa[k++]=tmp;

    }

    if(chose==0)

    {

       if(tmp)

      bb[l++] =tmp;

    }

}

void solve(int n,int m)

{

    for(int i=0;i<(1<<n);i++)

    {

        subset(n,i,1,N);

    }

    for(int i=0;i<(1<<m);i++)

    {

        subset(m,i,0,M);

    }

    for(int i=0;i<k;i++)

        for(int j=0;j<l;j++)

    {

        if(aa[i]==bb[j])

            ans++;

    }

    cout<<ans<<endl;

}

int main()

{

    int n,m;

    scanf("%d %d",&n,&m);

    for(int i=0;i<n;i++)

        cin>>N[i];

    for(int j=0;j<m;j++)

        cin>>M[j];

    solve(n,m);

}

AC 代码:(解决超时的问题)(应用map)

#include <iostream>

#include <iomanip>

#include <cstring>

#include <cstdio>

#include <map>

using namespace std;

 int k=0,l=0;

int N[18],M[18];

//int aa[18],bb[18];

map<long long,int> sa,sb;

map<long long,int> ::iterator it ;

void subset(int n,int s,int chose,int *a)// s 表示 2^n 种情况中的一种

{

    long long int tmp=0;

    for(int i=0;i<n;i++)

    {

        if(s&(1<<i))//如果两个位置上都是1则为真

       // printf("%d ",i);

          tmp+=a[i];

    }

    if(chose==1)

    {

       if(tmp)

       {

           if(sa.count(tmp))

            sa[tmp]++;

           else

            sa.insert(make_pair(tmp,1));

       }

    //  aa[k++]=tmp;

    }

    if(chose==0)

    {

       if(tmp)

       {

           if(sb.count(tmp))

            sb[tmp]++;

           else

            sb.insert(make_pair(tmp,1));

       }

    //  bb[l++] =tmp;

    }

}

void solve(int n,int m)

{

    long long int ans=0;

    for(int i=0;i<(1<<n);i++)

    {

        subset(n,i,1,N);

    }

    for(int i=0;i<(1<<m);i++)

    {

        subset(m,i,0,M);

    }

//    for(int i=0;i<k;i++)

//        for(int j=0;j<l;j++)

//    {

//        if(aa[i]==bb[j])

//            ans++;

//

//    }

  for ( it=sa.begin();it!=sa.end();it++)

  {

      if(sb.count(it->first))

      {

          ans+=((it->second) * sb[it->first]);

      }

  }

    printf("%lld\n",ans);

}

int main()

{

    int n,m;

    scanf("%d %d",&n,&m);

    for(int i=0;i<n;i++)

     scanf("%d",&N[i]);

    for(int j=0;j<m;j++)

         scanf("%d",&M[j]);

    solve(n,m);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: