• 关于二进制运算


    如果要求字符串s的子集  s是只由A和B组成的,则可以把A看作1 B看作0 进而把s转换成一个由1和0组成的二进制数 S

    则求S的子集就可以用以下代码来实现

    int len = s.size()
    for(int i=1; i< 1<<len; i++)
    {
        num[cnt++] = S & i;
    }

    因为从0到1<<len-1 包含了由1和0组成的所有情况 又因为&的性质 所以可以实现求子集

    例题:http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=820&pid=1001

    #include <iostream>
    #include <cstdio>
    #include <sstream>
    #include <cstring>
    #include <map>
    #include <set>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <cmath>
    #define rap(i, a, n) for(int i=a; i<=n; i++)
    #define MOD 2018
    #define LL long long
    #define ULL unsigned long long
    #define Pair pair<int, int>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define _  ios_base::sync_with_stdio(0),cin.tie(0)
    //freopen("1.txt", "r", stdin);
    using namespace std;
    const int maxn = 10010, INF = 0x7fffffff;
    int num[maxn], temp[maxn], vis[maxn];
    int n, m, k;
    
    int main()
    {
        int T, kase = 0;
        cin>> T;
        while(T--)
        {
            int ans = 0;
            mem(num, 0);
            mem(vis, 0);
            cin>> n >> m >> k;
            string str;
            rap(i, 1, n)
            {
                cin>> str;
                rap(j, 0, m-1)
                {
                    if(j != 0)
                        num[i] <<= 1;
                    if(str[j] == 'A')
                        num[i] ^= 1;
                }
              //  cout<< num[i] <<endl;
            }
            int res = 0;
            for(int i=1; i < 1<<m; i++)
            {
                mem(vis, 0);
                mem(temp, 0);
                int cnt = 0;
                res = 0;
                for(int j=1; j<=n; j++)
                {
                    int t = num[j] & i;
                    if(!vis[t]) temp[cnt++] = t;
                    vis[t]++;
                }
                for(int j=0; j<cnt; j++)
                {
                    for(int q=j+1; q<cnt; q++)
                    {
                        res += vis[temp[j]] * vis[temp[q]];
                    }
                }
                if(res >= k)
                    ans++;
            //    cout<< res <<endl;
            }
    
            printf("Case #%d: %d
    ", ++kase, ans);
        }
    
    
        return 0;
    }

    当然二进制也可以用于全排列

    例题

    hdu 1074

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.Scanner;
    
    public class Main{
        final static int maxn = 1<<16;
        final static int INF = 0xfffffff;
        public static int n;
        public static class node{
            String name = new String();
            int d,c;
            node(String name, int d, int c)
            {
                this.name = name;
                this.d = d;
                this.c = c;
            }
        } 
        public static ArrayList<node> list = new ArrayList<>();
        public static int[] pre = new int[maxn];
        public static void  print(int step)        //输出函数  类似 bfs最短路输出路径
        {
            if(step == 0)
                return;
            int t = 0;
            for(int i=0;i<n;i++)
            {
                if((step & (1<<i)) != 0 && (pre[step] & (1<<i)) == 0)
                {
                    t = i;
                    break;
                }
            }
            print(pre[step]);
            System.out.println(list.get(t).name);
        }
        public static void main(String[] args)  {
            Scanner cin = new Scanner(System.in);
            int cnt = 0;
            int T = cin.nextInt();
            while(T-- != 0)
            {
                list.clear();
                int[] dp = new int[maxn];
                Arrays.fill(pre, 0);
                n = cin.nextInt();
                for(int i=0;i<n;i++)
                {
                    String name = cin.next();
                    int d = cin.nextInt();
                    int c = cin.nextInt();
                    list.add(new node(name,d,c));
                }
                Arrays.fill(dp, INF);
                dp[0] = 0;
                for(int i=0;i < 1<<n;i++)  //已经做完的作业
                {
                    for(int j=0;j<n;j++)    // 即将要做的作业
                    {
                        if((i & (1<<j)) != 0) continue;   
                        int s = 0;
                        for(int k=0;k<n;k++)    //求出已经做完的作业的所耗费的时间  
                        {
                            if((i & (1<<k)) != 0)
                            {
                                s += list.get(k).c;
                            }
                        }
                        if(s + list.get(j).c > list.get(j).d)   //求出即将要做的作业是否超时
                            s = s + list.get(j).c - list.get(j).d;
                        else
                            s = 0;
                        if(dp[i|(1<<j)] > dp[i] + s)   
                        {
                            dp[i|(1<<j)] = dp[i] + s;
                            pre[i|(1<<j)] = i;
                        }
                    }
                }
                System.out.println(dp[(1<<n)-1]);
                print((1<<n)-1);
        
            }
    
        }
    }
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    旋转数组的最小数字
    二维数组中的查找问题--剑指offer面试题3
    百度软件开发实习生c++方向面经(一面)
    一些常考的智力题
    灵感闪现 篇 (一) 2d场景 3d 效果
    GameUnity 2.0 文档(四) 网格+四叉树 最优碰撞检测
    GameUnity 2.0 文档(三) 纸片人八方向
    GameUnity 2.0 文档(二) 纸片人系统
    GameUnity 2.0 文档(一) 事件机制
    GameUnity 2.0 发布倒计时
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9424583.html
Copyright © 2020-2023  润新知