#P1462. 第2题-小红修bug
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 163
            Accepted: 82
            Difficulty: 5
            
          
          
          
                       所属公司 : 
                              京东
                                
            
                        
              时间 :2023年8月19日
                              
                      
          
 
- 
                        算法标签>模拟          
 
第2题-小红修bug
思路:模拟
给定一个长度为n的01串记为s,以及2m个01串。这2m个01串每2个为一组,每组中的第一个01串,如果第i位为1,并且si=1,那么使si变为0。第二个01串中,如果第i位为1并且si=0,那么使si变为1。从m组01串中选出t组对s进行变换,求每次变换后s中1的个数。
题目比较长但是理解后题意很简单。同时,由于数据量不大,直接根据题意对01串遍历,根据题目条件进行模拟变换即可。
代码
C++
#include <iostream>
#include <vector>
using namespace std;
void solve() {
    int n;
    cin >> n;  // 读取 n,表示二进制字符串的长度
    
    auto read = [&]() -> int {
        int h = 0;
        string c;
        cin >> c;  // 读取二进制字符串
        for (int i = 0; i < n; i++) {
            h |= (c[i] - '0') << i;  // 将二进制字符串转换为整数
        }
        return h;
    };
    
    int h = read();  // 读取初始的二进制字符串
    
    int m;
    cin >> m;  // 读取 m,表示后续的操作数
    vector<int> f(m + 1), c(m + 1);  // 存储 f 数组和 c 数组
    
    for (int i = 1; i <= m; i++) {
        f[i] = read();  // 读取 f[i]
        c[i] = read();  // 读取 c[i]
    }
    
    int t;
    cin >> t;  // 读取 t,表示操作次数
    
    for (int i = 0; i < t; i++) {
        int x;
        cin >> x;  // 读取 x,表示当前操作的索引
        h &= ~f[x];  // 使用位运算取消 f[x] 的影响
        h |= c[x];   // 使用位运算应用 c[x]
        cout << __builtin_popcount(h) << endl;  // 统计二进制中的 1 的数量并输出
    }
}
int main() {
    int t = 1;
    // cin >> t;
    
    for (int i = 0; i < t; i++) {
        solve();
    }
    
    return 0;
}
python
def solve():
    n = int(input())  # 读取 n,表示二进制字符串的长度
    
    def read():
        h = 0
        c = input()  # 读取二进制字符串
        for i in range(n):
            h |= (int(c[i]) << i)  # 将二进制字符串转换为整数
        return h
    
    h = read()  # 读取初始的二进制字符串
    
    m = int(input())  # 读取 m,表示后续的操作数
    f = [0] * (m + 1)  # 存储 f 数组
    c = [0] * (m + 1)  # 存储 c 数组
    
    for i in range(1, m + 1):
        f[i] = read()  # 读取 f[i]
        c[i] = read()  # 读取 c[i]
        
    t = int(input())  # 读取 t,表示操作次数
    
    for _ in range(t):
        x = int(input())  # 读取 x,表示当前操作的索引
        h &= ~f[x]  # 使用位运算取消 f[x] 的影响
        h |= c[x]   # 使用位运算应用 c[x]
        print(bin(h).count('1'))  # 统计二进制中的 1 的数量并输出
def main():
    t = 1
    # t = int(input())
    
    for _ in range(t):
        solve()
if __name__ == "__main__":
    main()
Java
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int t = 1;
        for (int i = 0; i < t; i++) {
            solve(scanner);
        }
    }
    public static void solve(Scanner scanner) {
        int n = scanner.nextInt(); // 读取 n,表示二进制字符串的长度
        int h = readBinaryString(scanner, n); // 读取初始的二进制字符串
        int m = scanner.nextInt(); // 读取 m,表示后续的操作数
        int[] f = new int[m + 1];
        int[] c = new int[m + 1]; // 存储 f 数组和 c 数组
        for (int i = 1; i <= m; i++) {
            f[i] = readBinaryString(scanner, n); // 读取 f[i]
            c[i] = readBinaryString(scanner, n); // 读取 c[i]
        }
        int t = scanner.nextInt(); // 读取 t,表示操作次数
        for (int i = 0; i < t; i++) {
            int x = scanner.nextInt(); // 读取 x,表示当前操作的索引
            h &= ~f[x]; // 使用位运算取消 f[x] 的影响
            h |= c[x]; // 使用位运算应用 c[x]
            System.out.println(Integer.bitCount(h)); // 统计二进制中的 1 的数量并输出
        }
    }
    public static int readBinaryString(Scanner scanner, int n) {
        int h = 0;
        String c = scanner.next(); // 读取二进制字符串
        for (int i = 0; i < n; i++) {
            h |= (c.charAt(i) - '0') << i; // 将二进制字符串转换为整数
        }
        return h;
    }
}
        题目内容
小红是一个勤勤恳恳的程序员,这天,他要对自己以前写的程序修一修bug了。
小红有一个待修bug清单,用01串表示,其中第i位为“0”表示该bug已经修了,为“1”表示该bug待修。
小红有t个工具能够帮他修bug,每个工具能修的bug同样也是用01串表示,其中第i位为“1”表示该工具能够修理该bug,为“0”表示该工具不能够修理该bug。但是每个工具都有那么一点小问题,他们会引入bug,其中第i位为“1”表示该工具进行修理后,会引入该bug。
现在,小红告诉你他使用工具的顺序,他想知道,每使用一个工具后,还会剩下多少bug?
输入描述
第一行输入一个正整数n,代表待修bug清单的长度。
第二行输入一个长度为n的01串,代表待修bug清单内容。
第三行输入一个正整数m,代表工具的数量。
接下来的2∗m行,每2行描述一个工具:
第一行输入一个长度为n的01串,代表该工具能够修理哪些bug。
第二行输入一个长度为n的01串,代表该工具会产生哪些bug。
接下来的一行,输入一个正整数t,代表一共使用了t个工具
接下来的t行,每行输入一个正整数i,代表小红使用了第i个工具。
1≤n≤20
1≤m,t≤104
1≤i≤m
保证每个工具能够修理的bug和产生的bug不会重复。
输出描述
t个整数,表示当前剩余的bug。
样例
输入
4
1101
2
1010
0001
1001
0100
2
2
1
输出
1
2
说明
初始时,为1101,使用工具2后,为0100,剩余一个bug。
之后使用工具1,为0110,剩余两个bug。