zoukankan      html  css  js  c++  java
  • 2019牛客暑期多校训练营(第九场)Knapsack Cryptosystem——哈希表&&二进制枚举

    题意

    有长度为 $n$($1leq nleq 36$)的数列,给出 $s$,求和为 $s$ 的子集,保证子集存在且唯一。

    分析

    答案肯定是来自左右半边两部分组成的。

    如果我们用哈希表存一半,计算另一半的值 $v$,再在哈希表中查找 $s-v$,这样规模从 $2^{36}$ 降至 $2^{18}$,其实就是折半搜索。

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef  long long ll;
    ll n, s, a[40];
    ll A[1 << 20];
    unordered_map<ll, int>mp;
    
    int main()
    {
        scanf("%lld%lld", &n, &s);
        for(int i = 0;i < n;i++)  scanf("%lld", &a[i]);
    
        int l = n / 2;  //左边的长度
        for(int i = 0;i < (1 << l);i++)
            for(int j = 0;j < l;j++)
            {
                if((i >> j) & 1)
                    A[i] += a[j];
            }
    
        int r = n - l;  //右边的长度
        for(int i = 0;i < (1 << r);i++)
        {
            ll tmp = 0;
            for(int j = 0;j < r;j++)
            {
                if((i >> j) & 1)
                    tmp += a[j+l];
            }
            mp[tmp] = i;
        }
    
        //查找
        for(int i = 0;i < (1 << l);i++)
        {
            ll cha = s - A[i];
            if(mp.count(cha))
            {
                for(int j = 0;j < l;j++)
                {
                    if((i >> j) & 1)  printf("1");
                    else printf("0");
                }
                for(int j = 0;j < r;j++)
                {
                    if((mp[cha] >> j) & 1)  printf("1");
                    else  printf("0");
                }
                printf("
    ");
                break;
            }
        }
        return 0;
    }
  • 相关阅读:
    mybatis plus foreach 的用法
    mongodb聚合查询
    mongodb and 和 or 查询
    mongodb全文搜索
    时间参数的传递
    rabbitmq
    AOP各种的实现
    OWASP Top 10十大风险 – 10个最重大的Web应用风险与攻防
    OAuth2.0认证和授权机制讲解
    MySQL主从复制
  • 原文地址:https://www.cnblogs.com/lfri/p/11360824.html
Copyright © 2011-2022 走看看