#P2020. 2024.9.7-SF-第1题-矩阵格子
-
1000ms
Tried: 14
Accepted: 7
Difficulty: 3
2024.9.7-SF-第1题-矩阵格子
题目思路
由于题目给定的数据范围较小,因此可以直接采用暴力枚举的方式,遍历每个矩阵位置上的数字从0到3的所有可能取值。对于每一种可能的数字组合,逐行、逐列计算其异或值。然后将这些异或值与题目提供的目标值进行比较,判断是否满足题目要求的条件。
通过递归的深度优先搜索(DFS)方法,我们能够枚举出所有可能的3x3矩阵填充方式。每当完成一个矩阵填充后,计算该矩阵的行、列异或值,分别与输入的目标值数组进行对比。如果满足给定的限制条件,即至少有k行或k列的异或值与目标值相同,则增加符合条件的解的计数。
代码
python
arr = list(map(int, input().split())) # 输入目标数组
nums = [[0] * 3 for _ in range(3)] # 初始化 3x3 矩阵
k = int(input()) # 输入满足条件的最小数量
ans = 0 # 统计满足条件的方案数
def dfs(dep):
x, y = divmod(dep, 3) # 将深度转换为二维矩阵的坐标
if dep == 9: # 枚举完成后
row_xor = [0] * 3 # 用于存储每行的异或结果
col_xor = [0] * 3 # 用于存储每列的异或结果
for i in range(3):
for j in range(3):
row_xor[j] ^= nums[i][j] # 计算每行的异或值
col_xor[j] ^= nums[j][i] # 计算每列的异或值
valid = 0
for i in range(3):
if row_xor[i] == arr[i]: # 判断行异或值是否符合目标
valid += 1
if col_xor[i] == arr[i + 3]: # 判断列异或值是否符合目标
valid += 1
if valid >= k: # 如果满足的条件数量不小于 k
global ans
ans += 1
return
for i in range(4): # 对当前单元格尝试填入 0-3 的值
nums[x][y] = i
dfs(dep + 1) # 递归到下一个位置
dfs(0)
print(ans)
java
import java.util.Scanner;
public class Main {
static int[][] nums = new int[3][3]; // 初始化 3x3 矩阵
static int[] arr = new int[6]; // 输入目标数组
static int k; // 满足条件的最小数量
static int ans = 0; // 统计满足条件的方案数
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 输入目标数组
for (int i = 0; i < 6; i++) {
arr[i] = scanner.nextInt();
}
// 输入满足条件的最小数量
k = scanner.nextInt();
// 调用深度优先搜索
dfs(0);
// 输出结果
System.out.println(ans);
}
// 深度优先搜索函数
static void dfs(int dep) {
int x = dep / 3; // 将深度转换为二维矩阵的坐标
int y = dep % 3;
if (dep == 9) { // 如果枚举完成
int[] rowXor = new int[3]; // 存储每行的异或结果
int[] colXor = new int[3]; // 存储每列的异或结果
// 计算每行和每列的异或值
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
rowXor[j] ^= nums[i][j];
colXor[j] ^= nums[j][i];
}
}
int valid = 0;
// 判断每行的异或值是否符合目标
for (int i = 0; i < 3; i++) {
if (rowXor[i] == arr[i]) {
valid++;
}
if (colXor[i] == arr[i + 3]) {
valid++;
}
}
// 如果满足的条件数量不小于 k,计数器增加
if (valid >= k) {
ans++;
}
return;
}
// 尝试对当前单元格填入 0-3 的值
for (int i = 0; i < 4; i++) {
nums[x][y] = i;
dfs(dep + 1); // 递归处理下一个位置
}
}
}
c++
#include <iostream>
using namespace std;
int nums[3][3]; // 3x3 矩阵
int arr[6]; // 输入目标数组
int k; // 满足条件的最小数量
int ans = 0; // 统计满足条件的方案数
// 深度优先搜索函数
void dfs(int dep) {
int x = dep / 3; // 将深度转换为二维矩阵的坐标
int y = dep % 3;
if (dep == 9) { // 如果枚举完成
int rowXor[3] = {0}; // 存储每行的异或结果
int colXor[3] = {0}; // 存储每列的异或结果
// 计算每行和每列的异或值
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
rowXor[j] ^= nums[i][j];
colXor[j] ^= nums[j][i];
}
}
int valid = 0;
// 判断每行的异或值是否符合目标
for (int i = 0; i < 3; i++) {
if (rowXor[i] == arr[i]) {
valid++;
}
if (colXor[i] == arr[i + 3]) {
valid++;
}
}
// 如果满足的条件数量不小于 k,计数器增加
if (valid >= k) {
ans++;
}
return;
}
// 尝试对当前单元格填入 0-3 的值
for (int i = 0; i < 4; i++) {
nums[x][y] = i;
dfs(dep + 1); // 递归处理下一个位置
}
}
int main() {
// 输入目标数组
for (int i = 0; i < 6; i++) {
cin >> arr[i];
}
// 输入满足条件的最小数量
cin >> k;
// 调用深度优先搜索
dfs(0);
// 输出结果
cout << ans << endl;
return 0;
}
题目内容
小塔对于一个3∗3的矩阵,小塔可以在每一个格子中填上0到3之间的任何一个数。给出6个约束。
前三个数a1,a2,a3代表第一行异或和为a1,第二行异或和为a2,第三行异或和为a3。
后三个数a4,a5,a6代表第一列异或和a4,第二异或和a5,第三列异或和a6。
求有多少种填法使得以上约束至少满足k个。
输入描述
一行给出6个数ai(0≤ai≤7)
第二行给出一个数k(1≤k≤6)
输出描述
输出一行一个数代表答案。
样例1
输入
3 2 1 0 1 1
6
输出
2 5 6