zoukankan      html  css  js  c++  java
  • 富豪凯匹配串

    链接:https://ac.nowcoder.com/acm/contest/1114/C
    来源:牛客网

    题目描述
    有n个长度为m的文本串,每个串只含有’0’和’1’。接下来有Q次询问,每次给出一个长度为m的字符串,且只含有’0’,‘1’和’’。如10_1_1。下划线可以匹配’0’或’1’。即10_1_1可以匹配101111,101101,100111,100101四种串。每次询问求出n个文本串中有多少个可以与当前询问的串匹配。
    输入描述:
    第一行输入n,m
    接下来n行,每行输入一个长度为m的01串表示一个文本串。
    第n+2行输入Q
    接下来Q行,每行输入一个长度为m的字符串(只包含’0’,‘1’,’
    ’)。
    1<=n,m<=1000,1<=Q<=3000。
    输出描述:
    对于每次询问,输出n个文本串中有多少个与当前询问的串匹配。
    示例1
    输入
    复制
    5 6
    101101
    011011
    100110
    111000
    101111
    2
    1011_1
    1__1__
    输出
    复制
    2
    3
    说明
    第一次询问:有101101,101111与1011_1匹配
    第二次询问:有101101, 100110, 101111与1__1__匹配

    之前没学过bitset,今天做到一题, 原本我也想着压位, 但是1000长度怎么压,把我压死,也压不出来,结果题解就是压位,但是使用bitset这个东西来做。相当于压成一个数组, 然后这个数组还可以直接抑或上一个东西
    。。。所以就是3000 * 1000的复杂度了
    定义一个bitset s[N] , 设置成一个N维的数组 , 每维N个元素, 然后如果比较模板是否和这个相同, 可以两者直接&一下, 看看能不能得到一个特定的二进制串。
    所以下面就开始构造一个(a & s[i] == b),构造出一个a , 一个b , 这两个数组是根据模板串进行构造的, 目的就是为了检验s[i] 这个串能不能变化成模板串, 设模板串c , 如果c[j] == ‘1’ , 那么s[i][j] 肯定要是等于1的一个, 然后这个时候根据这个公式就得到a[j] = 1 , b[j] = 1 , 如果c[j] == ‘0’ , 那么就要检验s[i][j] == 0 ,这个时候a[j] = 1 , b[j] = 0 , 如果a[j] = 0 , 那么s[i][j] 不论为多少都会s[i][j] & a[j] = 0 , 所以只能为1 , b[j] 也只能为0 , 因为s[i][j] &a[j] = 0 , 第三种情况,就是c[j] == ‘_’ , 这个时候,s[i][j] 为多少都无所谓了, 所以直接a[j] = 0 , b[j] = 0 , 完全符合题意。
    然后直接枚举每个字符串和模板串进行&一下

    #include <iostream>
    #include <bitset>
    using namespace std;
    const int N = 1000 + 10 ;
    bitset<N> s[N] , a , b ;
    int main()
    {
        int n , m ;
        string c ;
        scanf("%d%d" , &n , &m) ;
        for(int  i = 0 ;i < n ;i ++)
        {
              cin >> c ;
              for(int j = 0 ; j < m ;j ++)
                 s[i][j] = c[j] - '0' ;
        }
        int Q ;
        cin >> Q ;
        while(Q --)
        {
            cin >> c ;
            for(int i = 0 ;i < m ;i ++)
            {
                
                if(c[i] == '0') a[i] = 1 , b[i] = 0 ; 
                else if(c[i] == '1') a[i] = 1 , b[i] = 1 ;
                else a[i] = 0 , b[i] = 0 ;
            }
            int cnt = 0 ;
            for(int i = 0 ;i < n ;i ++)
                 if((a & s[i] )== b) 
                      cnt ++ ;
            cout << cnt << endl ;
        }
    
        return 0 ;
    }
    
    每次做题提醒自己:题目到底有没有读懂,有没有分析彻底、算法够不够贪心、暴力够不够优雅。
  • 相关阅读:
    node中npm安装模块的网络问题
    微信开发
    7-49 打印学生选课清单 (25 分) 数据结构与算法题目集(中文)
    7-53 两个有序序列的中位数 (25 分) 数据结构与算法题目集(中文)
    练习4.2 平衡二叉树的根 (25 分) 浙大版《数据结构(第2版)》题目集
    习题4.3 是否二叉搜索树 (25 分) 浙大版《数据结构(第2版)》题目集
    实验3-1 求一元二次方程的根 (20 分) 《C语言程序设计实验与习题指导(第3版)》
    主元素问题
    未出现的最小正整数
    交换两个线性表位置(或循环移动数组元素)
  • 原文地址:https://www.cnblogs.com/spnooyseed/p/12870864.html
Copyright © 2011-2022 走看看