UVALive - 6886 Golf Bot (bitset)

该博客介绍了如何利用bitset高效解决UVA在线判题系统中编号为6886的Golf Bot问题。题目要求在给定的两个数列中选择1或2个数,求能组合成目标数的数量。原解法因DP复杂度过高导致超时,通过优化后采用bitset实现了AC(Accepted)的解决方案。文章详细阐述了bitset的基本操作和在该问题中的应用。
摘要由CSDN通过智能技术生成
题目链接:

UVA-6886

题目大意:

n n 个数 A[1,,n] m m 个数 B[1,,m];问在 A A 中选 1 个或 2 2 个数,能构成 (指相加) 多少个 B 中的数?

数据范围:

1n,m2e51Ai,Bi2e5 1 ≤ n , m ≤ 2 e 5 1 ≤ A i , B i ≤ 2 e 5

解题思路:

DP的复杂度不够,只想到一个比较好的暴力,送上一发TLE;后经 cp 大佬强力优化,终于在T,W之后看到了AC!
赛后发现大佬用 bitset 做的,嗯,,,bitset,了解一下?

定义:

主要有三种构造方式:

bitset <16> A;
bitset <16> B (0xfa2);    //十六进制构造
bitset <16> C (string("011001"));    //字符串构造

//A: 0000000000000000
//B: 0000111110100010
//C: 0000000000011001
基本运算:

什么与(&),或(|),非(~),异或(^),左移(<<),右移(>>) 都是有的!等于(==),不等于(!=)也都是有的。
C++ bitset 内部实现是非常 nice 的!很快!

基本函数:

bt.count() //1 的个数
bt.any() //返回是否有1
bt.none() //返回是否没有1
bt.set() //全部置为1
bt.reset() //全部置为0
bt.set(p) //把 p 位置为1
bt.reset(p) //把 p 位置为 0
bt.set(p, x) //把 p 位置为 x (x为0 或 1)
bt.flip() //全部取反
bt.flip(p) //把 p 位取反
bt.to_string() //转为 string


回到题目上来;只要把选 1 1 个数 和 选 2 个数能构成的状态处理出来,跟 B B 数组的状态与 (&) 一下,统计 1 的个数就可以了。

AC代码:

/**********************************************
 *Author*        :XzzF
 *Created Time*  : 2018/5/24 16:14:29
 *Ended  Time*  : 2018/5/24 16:23:52
*********************************************/

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <string>
#include <bitset>
using namespace std;
typedef long long LL;
const int inf = 1 << 30;
const LL INF = 1LL << 60;
const int MaxN = 200000;

int n, m;
int a[MaxN + 5];
bitset <MaxN + 1> A, B, ans;

int main()
{
    while(scanf("%d", &n) != EOF)
    {
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            A.set(a[i]);
        }
        scanf("%d", &m);
        for(int i = 1; i <= m; i++) {
            int x;
            scanf("%d", &x);
            B.set(x);
        }
        ans |= (B & A);    //只选1个数
        for(int i = 1; i <= n; i++)    //选2个数
            ans |= (B & (A << a[i]));
        printf("%d\n", ans.count());
        A.reset(); B.reset(); ans.reset();
    }
    return 0;
}



强行打一波广告:压位卡常题必备神器,bitset,值得拥有!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值