#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。