jzoj4274-终章-剑之魂【位运算,贪心】

正题


大意

有n把剑,每一把剑有一个值 ai a i ,然后两把剑的契合值是 ai and aj a i   a n d   a j ,求最大契合值。


解题思路

先把每个a转换成二进制
我们可以先从高位到低位。如果一个位数有超过一把剑那么这两个剑合在一起的值一定比任何这个位位为0的合在一起要大,所以我们就可以将这个位数为0的删去。但是如果这个位数有值的只有一把剑也没有用,因为没有任何一把武器可以和这个武器匹配,所以可以不用对这个位数进行处理。如果这个位数没有剑有值就更不用说了。


代码

#include
#include
using namespace std;
int a[1000001],n,maxs,k,ans;
bool v[1000001];
int main()
{
    freopen("sword.in","r",stdin);
    freopen("sword.out","w",stdout);
    scanf("%d",&n);
    k=n;
    for (int i=1;i<=n;i++)
      scanf("%d",&a[i]);
    for (int i=30;i>=0;i--)//枚举位数
    {
        int w=1<0;
        for (int i=1;i<=n;i++)
          if (a[i]&w&&!v[i])//统计这个位数有值的个数
            flag++;
        if (flag>=2)//超过两个
          for (int i=1;i<=n;i++)
            if (!v[i]&&!(a[i]&w))//删去这个位数位值的
            {
                v[i]=true;//标记删除
                k--;//剩余的减值
            }
        if (k==2) break;//只剩两个的话直接匹配
    }
    for (int i=1;i<=n;i++)//枚举匹配
    if (!v[i])
    {
        if (!ans) ans=a[i];
        else ans=ans&a[i];
    }
    printf("%d",ans);//输出
}

你可能感兴趣的:(其他,贪心)