富豪凯匹配串

链接: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 ;
}
每次做题提醒自己:题目到底有没有读懂,有没有分析彻底、算法够不够贪心、暴力够不够优雅。
原文地址:https://www.cnblogs.com/spnooyseed/p/12870864.html