火龙信奥
  • 首页
  • 课程
  • 题库
  • 打卡
    • 代码对战
    • 快速对战
  • 题单
  • 团队
  • 荣誉墙
  • 商城
  • 登录 / 注册

2025/26 冬季学期 第 7 次实验作业

作者: 作者的头像   huolong , 时间:2025-12-15 21:02:33 , 所有人可见, 阅读  15

编程实践课 - 程序设计导论 作业7

题目1:指针(5分)

创建一个名为Praktikum_7/Aufgabe_1的新项目,并在其中创建一个C++源文件zeiger.cpp。

a) 在main函数中定义三个int变量x、y和z,值分别为42、7和-11。然后声明三个指针a、b和c,并初始化这些指针,使a指向x,b指向y,c指向z。(1分)

b) 以表格形式输出声明的变量,格式如下:

--- 任务b)后的输出 ---
地址        内容        引用的值
变量 x    0x7fff0f3d69dc    42
变量 y    0x7fff0f3d69e0    7
变量 z    0x7fff0f3d69e4    -11
指针 a    0x7fff0f3d69e8    0x7fff0f3d69dc    42
指针 b    0x7fff0f3d69f0    0x7fff0f3d69e0    7
指针 c    0x7fff0f3d69f8    0x7fff0f3d69e4    -11

提示:使用空格和制表符(字符:\t)对齐列,例如printf("地址\t内容")。使用%p格式输出内存地址。(1分)

c) 交换指针值,使得之后a指向y,b指向x,然后输出变量。(1分) 限制:在此过程中,不得更改x和y的内容,也不能使用变量x和y本身。不要使用std::swap函数。

d) 用绘图(数字或手绘)说明交换操作。展示交换前和每次赋值后相关变量的状态。(1分)

e) 将变量z的值增加5。 限制:在此过程中,只能使用一个指针变量,不能直接使用变量z本身。(1分) 输出修改后的变量。

题目2:数独(8分)

在这个任务中,您需要实现一个递归的数独解题函数。数独是一个9x9的网格,被划分为3x3的子网格。目标是填充网格,使得每一行、每一列和每个3x3子网格都恰好包含1到9的数字各一次。

首先创建一个新目录Praktikum_7/Aufgabe_2,并在其中添加提供的sudoku.cpp文件。您需要实现以下函数:

a) 实现辅助函数bool naechsterZelle(int (feld)[9][9], int row, int col),它在给定的网格中找到第一个空单元格(值为0的单元格),并通过row和*col将位置传递给调用函数。如果所有单元格都已填充,则返回false,否则返回true。(2分)

b) 实现辅助函数bool darfEintragen(int (*feld)[9][9], int row, int col, int num),检查是否可以在给定位置插入数字num,而不会违反数独规则(即同行、同列、同3x3子网格中没有重复数字)。(3分)

c) 实现函数bool loeseSudoku(int (*feld)[9][9]),使用递归方法解决给定的数独谜题。使用模板中的示例测试您的函数。(3分)

解答 题目1实现 (zeiger.cpp)

#include <iostream>
#include <cstdio>
using namespace std;

int main() {
    // a) Define variables and initialize pointers
    int x = 42, y = 7, z = -11;
    int* a = &x;
    int* b = &y;
    int* c = &z;

    // b) Output after subtask b)
    cout << "--- Output after subtask b)---" << endl;
    printf("%-10s %-18s %-18s %s\n", "", "Address", "Content", "referenced value");
    printf("%-10s %-18p %-18d %d\n", "Variable x", (void*)&x, x, x);
    printf("%-10s %-18p %-18d %d\n", "Variable y", (void*)&y, y, y);
    printf("%-10s %-18p %-18d %d\n", "Variable z", (void*)&z, z, z);
    printf("%-10s %-18p %-18p %d\n", "Pointer a", (void*)&a, (void*)a, *a);
    printf("%-10s %-18p %-18p %d\n", "Pointer b", (void*)&b, (void*)b, *b);
    printf("%-10s %-18p %-18p %d\n", "Pointer c", (void*)&c, (void*)c, *c);

    // c) Swap pointer values (a should point to y, b to x)
    int* temp = a;
    a = b;
    b = temp;

    cout << endl << "--- Output after subtask c)---" << endl;
    printf("%-10s %-18s %-18s %s\n", "", "Address", "Content", "referenced value");
    printf("%-10s %-18p %-18d %d\n", "Variable x", (void*)&x, x, x);
    printf("%-10s %-18p %-18d %d\n", "Variable y", (void*)&y, y, y);
    printf("%-10s %-18p %-18d %d\n", "Variable z", (void*)&z, z, z);
    printf("%-10s %-18p %-18p %d\n", "Pointer a", (void*)&a, (void*)a, *a);
    printf("%-10s %-18p %-18p %d\n", "Pointer b", (void*)&b, (void*)b, *b);
    printf("%-10s %-18p %-18p %d\n", "Pointer c", (void*)&c, (void*)c, *c);

    // e) Increase the value of variable z by 5 (using only pointers)
    *c += 5;  // c points to z, so we increase the value via the pointer

    cout << endl << "--- Output after subtask e)---" << endl;
    printf("%-10s %-18s %-18s %s\n", "", "Address", "Content", "referenced value");
    printf("%-10s %-18p %-18d %d\n", "Variable x", (void*)&x, x, x);
    printf("%-10s %-18p %-18d %d\n", "Variable y", (void*)&y, y, y);
    printf("%-10s %-18p %-18d %d\n", "Variable z", (void*)&z, z, z);
    printf("%-10s %-18p %-18p %d\n", "Pointer a", (void*)&a, (void*)a, *a);
    printf("%-10s %-18p %-18p %d\n", "Pointer b", (void*)&b, (void*)b, *b);
    printf("%-10s %-18p %-18p %d\n", "Pointer c", (void*)&c, (void*)c, *c);

    return 0;
}

题目2代码实现 (sudoku.cpp)

#include <iostream>
using namespace std;

/**
 * @brief Finds the next empty cell in a Sudoku grid.
 * 
 * This function searches the provided Sudoku grid for the next cell that is empty (contains a 0).
 * If an empty cell is found, the function sets the row and column indices to the position of this cell.
 * 
 * @param grid A pointer to a 9x9 Sudoku grid.
 * @param row A pointer to an integer where the row index of the next empty cell will be stored.
 * @param col A pointer to an integer where the column index of the next empty cell will be stored.
 * @return `true` if an empty cell is found, `false` if the grid is completely filled.
 */
bool nextEmptyCell(int (*grid)[9][9], int* row, int* col) {
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            if ((*grid)[i][j] == 0) {
                *row = i;
                *col = j;
                return true;
            }
        }
    }
    return false; // No empty cells found
}

/**
 * @brief Checks if a number can be placed in a specific cell of a Sudoku puzzle.
 * 
 * This function checks if the given number `num` can be inserted into the cell at position `(row, col)`
 * of the Sudoku puzzle `grid` without violating the Sudoku rules.
 * 
 * @param grid A pointer to a 9x9 Sudoku grid.
 * @param row The row of the cell to be checked.
 * @param col The column of the cell to be checked.
 * @param num The number to be inserted into the cell.
 * @return `true` if the number can be inserted into the cell, otherwise `false`.
 */
bool canPlaceNumber(int (*grid)[9][9], int row, int col, int num) {
    // Check the row
    for (int i = 0; i < 9; i++) {
        if ((*grid)[row][i] == num) {
            return false;
        }
    }

    // Check the column
    for (int i = 0; i < 9; i++) {
        if ((*grid)[i][col] == num) {
            return false;
        }
    }

    // Check the 3x3 subgrid
    int startRow = row - row % 3;
    int startCol = col - col % 3;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if ((*grid)[startRow + i][startCol + j] == num) {
                return false;
            }
        }
    }

    return true;
}

/**
 * @brief Solves a given Sudoku puzzle recursively.
 * 
 * This function attempts to solve a given Sudoku puzzle by recursively
 * placing numbers in empty cells and checking if the placement is valid.
 * If a valid solution is found, it returns true. Otherwise, it returns false.
 * 
 * @param grid A pointer to a 9x9 Sudoku grid. Empty cells are marked with 0.
 * @return `true` if the Sudoku can be solved, otherwise `false`.
 */
bool solveSudoku(int (*grid)[9][9]) {
    int row, col;

    // Find the next empty cell
    if (!nextEmptyCell(grid, &row, &col)) {
        // No more empty cells - the Sudoku is solved
        return true;
    }

    // Try placing numbers from 1 to 9 in the empty cell
    for (int num = 1; num <= 9; num++) {
        if (canPlaceNumber(grid, row, col, num)) {
            // Place the number and continue recursively
            (*grid)[row][col] = num;

            if (solveSudoku(grid)) {
                return true;
            }

            // Backtracking: If the number doesn't lead to a solution, remove it
            (*grid)[row][col] = 0;
        }
    }

    return false; // No number fits in this cell
}

/**
 * @brief Displays a Sudoku grid.
 * 
 * This function prints a 9x9 Sudoku grid to the standard output. Each cell
 * is separated by a space, and the grid is divided into 3x3 subgrids by vertical and
 * horizontal lines.
 * 
 * @param grid A pointer to a 9x9 array representing the Sudoku grid. Each
 * element should be an integer between 1 and 9. Cells with values
 * outside this range are displayed as '.'.
 */
void printSudoku(int (*grid)[9][9]) {
    for (int i = 0; i < 9; ++i) {
        for (int j = 0; j < 9; ++j) {
            std::cout << (char)((*grid)[i][j]<=9 && (*grid)[i][j]>=1 ? (*grid)[i][j]+'0' : '.') << " ";
            if ((j + 1) % 3 == 0 && j != 8) std::cout << "| ";
        }
        std::cout << endl;
        if ((i + 1) % 3 == 0 && i != 8) {
            for (int k = 0; k < 21; ++k) {
                std::cout << "-";
            }
            std::cout << endl;
        }
    }
}

int main() {
    int grid[9][9] = {
        {0, 0, 9, 0, 0, 0, 0, 0, 0},
        {0, 3, 0, 2, 0, 0, 0, 0, 0},
        {0, 0, 0, 0, 8, 4, 0, 5, 1},
        {0, 0, 0, 0, 3, 2, 9, 0, 0},
        {0, 0, 6, 0, 0, 0, 0, 2, 0},
        {0, 8, 0, 0, 0, 0, 5, 7, 0},
        {0, 0, 0, 0, 6, 0, 7, 3, 0},
        {7, 0, 0, 4, 0, 0, 0, 0, 0},
        {4, 0, 5, 0, 0, 0, 0, 9, 0}
    };

    cout << "Sudoku puzzle:" << endl;
    printSudoku(&grid);

    if (solveSudoku(&grid)) {
        std::cout << endl << "Solution:" << std::endl;
        printSudoku(&grid);
        return 0;
    } else {
        std::cout << "No solution found." << std::endl;
        return 1;
    }
}

题目1 d) 部分的图示说明

Before swap:
+-------+     +-----+     +-------+     +-----+     +-------+     +-----+
| a     |---->| x   |     | b     |---->| y   |     | c     |---->| z   |
+-------+     +-----+     +-------+     +-----+     +-------+     +-----+
              | 42  |                   |  7  |                   | -11 |
              +-----+                   +-----+                   +-----+

After "temp = a":
+-------+     +-----+     +-------+     +-----+     +-------+     +-----+     +-------+
| a     |---->| x   |     | b     |---->| y   |     | c     |---->| z   |     | temp  |----+
+-------+     +-----+     +-------+     +-----+     +-------+     +-----+     +-------+    |
              | 42  |                   |  7  |                   | -11 |                 |
              +-----+                   +-----+                   +-----+                 |
                                                                                          |
After "a = b":                                                                           |
+-------+     +-----+     +-------+     +-----+     +-------+     +-----+     +-------+    |
| a     |----------+      | b     |---->| y   |     | c     |---->| z   |     | temp  |----+
+-------+        |        +-------+     +-----+     +-------+     +-----+     +-------+
                 |                    |  7  |                   | -11 |
                 |                    +-----+                   +-----+
                 |
                 |        +-----+
                 +------->| x   |
                          +-----+
                          | 42  |
                          +-----+

After "b = temp":
+-------+     +-----+     +-------+     +-----+     +-------+     +-----+
| a     |---->| y   |     | b     |---->| x   |     | c     |---->| z   |
+-------+     +-----+     +-------+     +-----+     +-------+     +-----+
              |  7  |                   | 42  |                   | -11 |
              +-----+                   +-----+                   +-----+

Final state: a points to y, b points to x

—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com

©2026加盟我们 | 关于我们 | ACM课程 | 常见问题 | 成果墙 | 评测记录 | 浙ICP备2021013995号
在线画图 | OI WIki | 打字练习
火龙信奥
请输入登录信息


请完成安全验证
验证码底图 滑块
向右拖动滑块完成验证
请输入用户名 / 绑定的手机号码



请输入注册信息(手机号验证码注册)





验证码5分钟有效,60秒内不可重复获取,每日最多3次

微信登录

微信登录二维码

正在生成二维码...

账号已过期,请续期。
去续期

绑定手机号

📱

为了更好地保护您的账号安全,享受完整的平台服务

请您尽快绑定手机号码