首页 > 试题广场 >

取数游戏

[编程题]取数游戏
  • 热度指数:1295 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
{\hspace{15pt}}一个 N\times M 的由非负整数构成的数字矩阵,你需要在其中取出若干个数字,使得取出的任意两个数字不相邻(若一个数字在另外一个数字相邻 8 个格子中的一个即认为这两个数字相邻),求取出数字和最大是多少。

输入描述:
{\hspace{15pt}}第一行有一个正整数 T1\leqq T\leqq 20,表示了有 T 组数据。

{\hspace{15pt}}对于每一组数据,第一行有两个正整数 N,M1\leqq N, M\leqq 6,表示了数字矩阵为 N 行 M 列。

{\hspace{15pt}}接下来 N 行,每行 M 个非负整数,描述了这个数字矩阵,满足 1 \leqq a_{i,j}\leqq 10^5


输出描述:
{\hspace{15pt}}输出共 T 行,每行一个非负整数,输出所求得的答案。
示例1

输入

1
3 3
1 1 1
1 1 1
1 1 1

输出

4
AI太强了,下面是deepseek写出的代码,程序员可以失业了。
#include <stdio.h>
#include <string.h>

int N, M;
int max_result;

// 解决函数:使用DFS搜索所有可能的选取方案
// matrix: 数字矩阵
// used: 标记哪些位置已经被选取
// x, y: 当前要处理的位置坐标
// sum: 当前已选取数字的总和
void solve(int matrix[N][M], int used[N][M], int x, int y, int sum) {
    // 如果已经处理完所有行,更新最大值并返回
    if (x >= N) {
        if (sum > max_result) max_result = sum;
        return;
    }
    
    // 计算下一个要处理的位置
    int next_x = x;
    int next_y = y + 1;
    // 如果当前行处理完了,移动到下一行的第一个位置
    if (next_y >= M) {
        next_x = x + 1;
        next_y = 0;
    }
    
    // 选择1:不选当前位置的数字
    // 直接跳到下一个位置,总和不变
    solve(matrix, used, next_x, next_y, sum);
    
    // 选择2:尝试选取当前位置的数字
    // 首先检查是否能选取(周围8个方向没有已选的数字)
    int can_choose = 1; // 假设可以选取
    
    // 检查周围8个方向(包括对角线)
    for (int dx = -1; dx <= 1; dx++) {
        for (int dy = -1; dy <= 1; dy++) {
            // 跳过当前位置自身
            if (dx == 0 && dy == 0) continue;
            
            // 计算相邻位置的坐标
            int neighbor_x = x + dx;
            int neighbor_y = y + dy;
            
            // 检查相邻位置是否在矩阵范围内且已经被选取
            if (neighbor_x >= 0 && neighbor_x < N && 
                neighbor_y >= 0 && neighbor_y < M && 
                used[neighbor_x][neighbor_y]) {
                can_choose = 0; // 发现相邻位置已选,不能选当前位置
                break;
            }
        }
        // 如果已经确定不能选,提前结束检查
        if (!can_choose) break;
    }
    
    // 如果当前位置可以选取
    if (can_choose) {
        // 标记当前位置为已选取
        used[x][y] = 1;
        
        // 递归处理下一个位置,总和加上当前数字的值
        solve(matrix, used, next_x, next_y, sum + matrix[x][y]);
        
        // 回溯:取消当前位置的选取标记
        used[x][y] = 0;
    }
}

int main() {
    int T;
    scanf("%d", &T);
    
    // 处理每组测试数据
    while (T--) {
        // 读取矩阵大小
        scanf("%d %d", &N, &M);
        int matrix[N][M];    // 存储数字矩阵
        int used[N][M];      // 标记矩阵,记录哪些位置被选取
        
        // 初始化used数组为0(所有位置都未选取)
        memset(used, 0, sizeof(used));
        
        // 读取数字矩阵
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                scanf("%d", &matrix[i][j]);
            }
        }
        
        // 初始化最大结果为0
        max_result = 0;
        
        // 从矩阵的左上角(0,0)开始搜索
        solve(matrix, used, 0, 0, 0);
        
        // 输出最大和
        printf("%d\n", max_result);
    }
    return 0;
}


发表于 今天 16:54:02 回复(0)