回溯法求解3*3填数问题

问题描述

填数字游戏问题:

在 3×3 个方格的方阵中要填入数字 1-9,每个方格填一个整数,每个数只能填一次,使得每行每列的和相等。请问是否存在这样的填法,如果是,求出满足这个要求的数字填法。

求解思路

1 .遍历已生成的数独二维数组,得出空白格子的数目。

2 .从第一个空白格子开始,按照题目要求的规范,检验每行每列的和,找出其所有可行解,存入数组。利用最后一个可行解,进行下一步运算。

3 .对剩下的格子进行同样的操作。

4 .如遇到无解的情况,则进行回溯操作。继续重复上述运算。

5 .当所有空白格子填满,所得结果,即为数独的解。

实现代码:

import numpy as np


grid = [[ 0,0,0],[ 0,0,0],[0,0,0]]


def possible(y, x, n):
    global grid

    for p in range(3):
        for q in range(3):
            if n == grid[p][q]:
                return False

    couty = 0
    for i in range(3) :
        if grid[y][i]>0:
            couty+=1
        if  (couty>1) and ((grid[y][0]+grid[y][1]+ grid[y][2]+n) != 15):
            couty = 0
            return False
    coutx = 0
    for i in range(3):
        if grid[i][x] > 0:
            coutx += 1
        if (coutx > 1) and ((grid[0][x] + grid[1][x] +  grid[2][x] + n) != 15):
            coutx = 0
            return False

    return True


def solve():
    global grid
    for y in range(3):
        for x in range(3):
            if grid[y][x] == 0:
                for n in range(1, 10):
                    if possible(y, x, n):
                        grid[y][x] = n
                        solve()
                        grid[y][x] = 0
                return

    print(np.matrix(grid), '\n')

运行结果:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
七巧板着色问题一个经典的回溯法问题,可以用C语言实现。以下是一个简单的实现: ```c #include <stdio.h> #include <stdbool.h> // 七巧板的形状 const int pieces[7][4][2] = { {{0, 0}, {0, 1}, {0, 2}, {1, 1}}, // F {{0, 0}, {0, 1}, {0, 2}, {1, 2}}, // L {{0, 0}, {0, 1}, {0, 2}, {1, 0}}, // P {{0, 0}, {0, 1}, {1, 1}, {1, 0}}, // Q {{0, 0}, {0, 1}, {1, 1}, {2, 1}}, // T {{0, 0}, {0, 1}, {1, 1}, {1, 2}}, // U {{0, 0}, {0, 1}, {1, 1}, {2, 1}} // V }; // 定义七巧板的颜色 const char colors[6] = {'R', 'G', 'B', 'Y', 'P', 'O'}; // 定义七巧板的状态 char board[5][4]; bool used[7]; // 打印七巧板的状态 void print_board() { for (int i = 0; i < 5; i++) { for (int j = 0; j < 4; j++) { printf("%c ", board[i][j]); } printf("\n"); } printf("\n"); } // 判断是否可以放置七巧板 bool can_place(int piece, int x, int y) { for (int i = 0; i < 4; i++) { int nx = x + pieces[piece][i][0]; int ny = y + pieces[piece][i][1]; if (nx < 0 || nx >= 5 || ny < 0 || ny >= 4 || board[nx][ny] != '-') { return false; } } return true; } // 放置七巧板 void place(int piece, int x, int y, char color) { for (int i = 0; i < 4; i++) { int nx = x + pieces[piece][i][0]; int ny = y + pieces[piece][i][1]; board[nx][ny] = color; } used[piece] = true; } // 移除七巧板 void remove(int piece, int x, int y) { for (int i = 0; i < 4; i++) { int nx = x + pieces[piece][i][0]; int ny = y + pieces[piece][i][1]; board[nx][ny] = '-'; } used[piece] = false; } // 回溯法求解七巧板着色问题 bool solve() { int x = -1, y = -1; for (int i = 0; i < 5; i++) { for (int j = 0; j < 4; j++) { if (board[i][j] == '-') { x = i; y = j; break; } } if (x != -1) { break; } } if (x == -1) { return true; // 所有位置都被满,找到了一个解 } for (int i = 0; i < 7; i++) { if (!used[i]) { for (int j = 0; j < 6; j++) { if (can_place(i, x, y)) { place(i, x, y, colors[j]); if (solve()) { return true; // 找到一个解,直接返回 } remove(i, x, y); } } } } return false; // 没有找到解 } // 主函数 int main() { // 初始化 for (int i = 0; i < 5; i++) { for (int j = 0; j < 4; j++) { board[i][j] = '-'; } } for (int i = 0; i < 7; i++) { used[i] = false; } // 求解 if (solve()) { print_board(); } else { printf("No solution found.\n"); } return 0; } ``` 在这个实现中,我们使用了一个5x4的二维数组来表示七巧板的状态,其中空白的位置使用字符`'-'`表示。在`can_place`函数中,我们判断了七巧板是否可以被放置在指定的位置上。在`place`函数中,我们将七巧板放置在指定的位置上,并将其标记为已使用。在`remove`函数中,我们将七巧板从指定的位置上移除,并将其标记为未使用。 `solve`函数是回溯法的核心函数。在这个函数中,我们首先查找空白的位置,然后依次尝试每个未使用的七巧板是否可以被放置在该位置上。如果可以,我们就将该七巧板放置在该位置上,并递归调用`solve`函数。如果找到了一个解,直接返回即可。如果没有找到解,返回`false`表示没有找到解。 最后,在主函数中,我们初始化七巧板的状态并调用`solve`函数求解。如果找到了一个解,就打印出来;否则,输出`No solution found.`表示没有找到解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BLK_mamba

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值