Bitset训练题

痛,太痛了~

两天,3道bitset,

学!都可以学!

例1. https://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1003&cid=1044

题解:

            

代码:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <bitset>

using namespace std;
const int N = 1100;
bitset<N> f[N], g[N];
int n, m;

void solve()
{
    cin >> n >> m;
    for(int i = 0 ; i <= 1024; i ++ ) f[i].reset(), g[i].reset();
    f[0][0] = 1; 
    for(int i = 1 ; i <= n ; i ++ )
    {
        int w, v;
        cin >> v >> w;
        for(int j = 0 ; j < 1024 ; j ++ )
        {
            g[j] = f[j];
            g[j] <<= v;
        }
        for(int j = 0 ; j < 1024 ; j ++ )
        {
            f[j] |= g[j ^ w];
        }
    }
    bool flag = false;
    for(int i = 1024 ; i >= 0 ; i -- )
        if(f[i][m]) 
        {
            flag = true;
            cout << i << endl;
            return ;
        }
     if(!flag) puts(“-1”); // 处理无解情况
}

int main()
{
    int T = 1;
    cin >> T;
    while(T -- ) solve();
    return 0;
}
 

例2. https://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1004&cid=1044

题解:

 

 

代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <bitset>

using namespace std;
const int N = 2010;
int n, m, a[N], b[N];
bitset<N> p[N];
struct Edge
{
    int a, b, w;
    bool operator < (const Edge &t) const
    {
        return w < t.w;
    }
}edges[N * N];
bool st[N * N];
int primes[N * N], cc;
int cnt, ans;

void init()
{ // 线性筛法
    for(int i = 2 ; i < 200010 ; i ++ )
    {
        if(!st[i]) primes[cnt ++ ] = i;
        for(int j = 0 ; primes[j] * i < 200010 ; j ++ )
        {
            st[primes[j] * i] = true;
            if(i % primes[j] == 0) break;
        }
    }
}

int calc(int i, int j)
{
    return abs(a[i] - a[j]) + abs(b[i] - b[j]);
}

void solve()
{
    cin >> n >> m;
    cnt = 0, ans = 0;
    for(int i = 0 ; i <= n ; i ++ ) p[i].reset();
    for(int i = 1 ; i <= n ; i ++ ) cin >> a[i] >> b[i];
    for(int i = 1 ; i <= n ; i ++ )
        for(int j = i + 1; j <= n ; j ++ ) 
            edges[++ cnt] = {i, j, calc(i, j)};
    sort(edges + 1, edges + cnt + 1); // 按距离排序,先枚举的边一定比当前的小,做好标记即可。
    for(int i = 1 ; i <= cnt ; i ++ )
    {
        int a = edges[i].a, b = edges[i].b, w = edges[i].w;
        if(!st[w]) ans += (p[a] ^ p[b]).count(); // p[a]表示距离比w小的点的数量 , st表示他是不是素数
        p[a][b] = 1, p[b][a] = 1;
    }
    cout << ans << endl;
}

int main()
{
    init();
    int T = 1;
    cin >> T;
    while(T -- ) solve();
    return 0;
}

 

例3. https://acm.hdu.edu.cn/contest/problem?cid=1045&pid=1003

 

 

题解:

    

 

 

 

 

posted @ 2022-07-21 20:32  往哉生生  阅读(26)  评论(0编辑  收藏  举报