【HDU4016】Magic Bitwise And Operation(dfs)

题目链接

Magic Bitwise And Operation

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 1716    Accepted Submission(s): 709


 

Problem Description

Given n integers, your task is to pick k out of them so that the picked number are minimum when do bitwise “AND” among all of them.
For example, there are three integers 5, 6 and 7. You are asked to pick two of them. Your possible strategy is (5, 6), (5, 7) or (6, 7). The values when do bitwise and all the picked numbers together are as follows:
5 and 6 = 4
5 and 7 = 5
6 and 7 = 6
The smallest one is 4.

 

Input

There are multiple test cases for this problem. The first line of the input contains an integer denoting the number of test cases.
  For each test case, there are two integers in the first line: n and k, denoting the number of given integers and the number of integers you are asked to pick out. n <= 40
  The second line contains the n integers. You may assume that all integers are small than 2^60.

Notes: There are about one thousand randomly generated test cases. Fortunately 90% of them are relatively small.

 

Output

For each test case, output only one integer is the smallest possible value.

 

Sample Input

 

3 3 2 5 6 7 8 2 238 153 223 247 111 252 253 247 40 10 1143632830316675007 558164877202423550 1152356080752164603 1143911006781551605 1132655005501751263 1152919305583327167 1141662230660382702 862439259920596463 1151777428397603327 1008771132016295871 855666336963428351 1151795583225167807 1152634943314572791 1071856693060561407 1132650872803426303 1124211056982081471 1152917106425982911 1152815392070041535 1080863910568853481 288230371856350975 1080720560532488126 864686455262281727 576460673919991167 574191342855241589 1152233760050118651 1152921504605798263 1152912708241186815 1079738008506187487 1075796261476483027 1080854478820730879 1152885219917823999 1151725162940854259 1147529498501577715 571956602920235519 1134545630643616248 1152921218991521790 1152921496000052703 1142788250826440703 1151654831778151421 1152780747522637695

 

Sample Output

 

Case #1: 4 Case #2: 9 Case #3: 36028797086245424

 

Source

The 36th ACM/ICPC Asia Regional Shanghai Site —— Warmup

【题意】

给n个数字,将其中的k个数字并起来,得到一个最小的答案,输出该值。

【解题思路】

不得不说队友的直觉真是太准了...虽然看这数据我应该也要想到的!恕我太菜!直接搜就好,但有的情况需要剪枝,不然是会过不去的。

因为答案一定是越并越小,所以只需要满足当前搜到的值与后面的值并起来的答案比之前的答案还要大,这就说明它就算往后把所有的数都并起来都无法更新答案,那么就没有必要往下搜了。这种情况剪枝之后就可以过啦。

【代码】

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL INF=(1LL<<61)-1;
LL a[55],b[55];
int vis[55];
int n,k;
LL ans=INF;
void init()
{
    for(int i=0;i<n;i++)b[i]=INF;
    for(int i=0;i<n;i++)
        for(int j=i;j<n;j++)
            b[i]=b[i]&a[j];
    /*for(int i=0;i<n;i++)
        printf("i=%d,%lld\n",i,b[i]);*/
}
void dfs(int pos,int num,LL x)
{
    if(k==num)
    {
        ans=min(ans,x);
        return;
    }
    LL t=x;
    if((b[pos]&t)>=ans)return;
    if(pos==n)return;
    dfs(pos+1,num+1,x&a[pos]);
    dfs(pos+1,num,x);
}
int main()
{
    int T,kase=1;
    scanf("%d",&T);
    while(T--)
    {
        ans=INF;
        memset(vis,0,sizeof(vis));
        scanf("%d%d",&n,&k);
        for(int i=0;i<n;i++)
            scanf("%lld",&a[i]);
        sort(a,a+n);
        init();
        dfs(0,0,INF);
        printf("Case #%d: %lld\n",kase++,ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39826163/article/details/83240289
今日推荐