【不可思议算法】一个N*N的方格,从左上到右下,总共有多少种走法

一个N*N的方格,从左上到右下,总共有多少种走法,不重复经过同一交点。

先看几个视频:

[不可思议的计算法]和大姐姐一起来计算! - 嗶哩嗶哩 - ( ゜- ゜)つロ 乾杯~ - bilibili.tv

还记得那个数方格的大姐姐么 - 嗶哩嗶哩 - ( ゜- ゜)つロ 乾杯~ - bilibili.tv

那些你所不知道的数字单位 - 嗶哩嗶哩 - ( ゜- ゜)つロ 乾杯~ - bilibili.tv

 

用最笨的搜索与回溯

(大写的N的值对应方格的边长,下面的代码N=5即是5*5的方格)

#include <fstream>

const int N = 5 , n = N + 1  , m = n + 2 ;
int way[20] = { 0 } ; void wpp( int lev ) { ++way[ lev ]; if ( way[ lev ] == 10000 ) { way[ lev ] = 0 ; wpp( lev + 1 ) ; } } void path( bool grid[20][20] , int i , int j , int dir ) { if ( dir == 1 ) ++j ; else if ( dir == 2 ) ++i ; else if ( dir == 3 ) --j ; else --i ; if ( grid[i][j] ) return ; if ( i == n && j == n ) { wpp(1) ; wpp(1) ; return ; } grid[i][j] = true ; path( grid , i , j , 1 ) ; path( grid , i , j , 2 ) ; path( grid , i , j , 3 ) ; path( grid , i , j , 4 ) ; grid[i][j] = false ; return ; } int main() { int i = 1 , j = 1 ; bool grid[20][20] = {false} ; for ( int a = 0 ; a != m ; ++a ) { grid[0][a] = true ; grid[m-1][a] = true ; grid[a][0] = true ; grid[a][m-1] = true ; } grid[i][j] = true ; path( grid , i , j , 1 ) ; printf( "%dx%d\n" , N , N ) ; int bit = 19 ; for ( ; ! way[ bit ] ; --bit ) ; printf( " %4d" , way[ bit-- ] ) ; while ( bit != 0 ) printf( " %04d" , way[ bit-- ] ) ; }

 

 

 

转载于:https://www.cnblogs.com/FZQL/archive/2013/05/21/3089962.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 好的,我可以为您提供一个棋盘覆盖算法的演示代码,以下是代码: #include <iostream> using namespace std; const int MAXN = 1 << 6; // 棋盘大小 int board[MAXN][MAXN]; // 棋盘 int tile = 1; // 当前骨牌编号 // x, y: 当前棋盘左上角的坐标 // tx, ty: 特殊方格的坐标 void chessboard(int x, int y, int tx, int ty, int size) { if (size == 1) return; // 递归边界 int t = tile++; // 当前骨牌编号 int s = size / 2; // 当前棋盘大小的一半 // 特殊方格左上角 if (tx < x + s && ty < y + s) { chessboard(x, y, tx, ty, s); // 递归处理左上角棋盘 } else { board[x + s - 1][y + s - 1] = t; // 否则特殊方格下角 chessboard(x, y, x + s - 1, y + s - 1, s); // 递归处理左上角棋盘 } // 特殊方格上角 if (tx < x + s && ty >= y + s) { chessboard(x, y + s, tx, ty, s); // 递归处理上角棋盘 } else { board[x + s - 1][y + s] = t; // 否则特殊方格在左下角 chessboard(x, y + s, x + s - 1, y + s, s); // 递归处理上角棋盘 } // 特殊方格在左下角 if (tx >= x + s && ty < y + s) { chessboard(x + s, y, tx, ty, s); // 递归处理左下角棋盘 } else { board[x + s][y + s - 1] = t; // 否则特殊方格上角 chessboard(x + s, y, x + s, y + s - 1, s); // 递归处理左下角棋盘 } // 特殊方格下角 if (tx >= x + s && ty >= y + s) { chessboard(x + s, y + s, tx, ty, s); // 递归处理下角棋盘 } else { board[x + s][y + s] = t; // 否则特殊方格左上角 chessboard(x + s, y + s, x + s, y + s, s); // 递归处理下角棋盘 } } int main() { int k, x, y; cin >> k >> x >> y; // 输入棋盘大小和特殊方格坐标 board[x][y] = ; // 特殊方格编号为 chessboard(, , x, y, 1 << k); // 递归处理棋盘 for (int i = (1 << k) - 1; i >= ; i--) { // 输出棋盘 for (int j = ; j < (1 << k); j++) { cout << board[i][j] << " "; } cout << endl; } return ; } ### 回答2: 下面是一个简单的棋盘覆盖算法演示的代码: ```python def chessboard_cover(board, tr, tc, dr, dc, size, count): global tile_count # 如果棋盘大小为1,则直接覆盖 if size == 1: return tile_count += 1 t = tile_count sub_size = size // 2 # 左上角子棋盘 if dr < tr + sub_size and dc < tc + sub_size: chessboard_cover(board, tr, tc, dr, dc, sub_size, count) else: board[tr + sub_size - 1][tc + sub_size - 1] = t chessboard_cover(board, tr, tc, tr + sub_size - 1, tc + sub_size - 1, sub_size, count) # 上角子棋盘 if dr < tr + sub_size and dc >= tc + sub_size: chessboard_cover(board, tr, tc + sub_size, dr, dc, sub_size, count) else: board[tr + sub_size - 1][tc + sub_size] = t chessboard_cover(board, tr, tc + sub_size, tr + sub_size - 1, tc + sub_size, sub_size, count) # 左下角子棋盘 if dr >= tr + sub_size and dc < tc + sub_size: chessboard_cover(board, tr + sub_size, tc, dr, dc, sub_size, count) else: board[tr + sub_size][tc + sub_size - 1] = t chessboard_cover(board, tr + sub_size, tc, tr + sub_size, tc + sub_size - 1, sub_size, count) # 下角子棋盘 if dr >= tr + sub_size and dc >= tc + sub_size: chessboard_cover(board, tr + sub_size, tc + sub_size, dr, dc, sub_size, count) else: board[tr + sub_size][tc + sub_size] = t chessboard_cover(board, tr + sub_size, tc + sub_size, tr + sub_size, tc + sub_size, sub_size, count) # 棋盘覆盖算法演示函数 def chessboard_cover_demo(size, dr, dc): global tile_count # 初始化棋盘 board = [[0] * size for _ in range(size)] # 对起始位置进行标记 board[dr][dc] = -1 # 设置全局变量 tile_count = 0 # 调用棋盘覆盖算法 chessboard_cover(board, 0, 0, dr, dc, size, tile_count) # 输出棋盘 print("棋盘覆盖结果:") for row in board: for val in row: print("%3d" % val, end=" ") print() # 测试代码 chessboard_cover_demo(8, 0, 0) ``` 这段代码实现了棋盘覆盖算法的演示,将一个棋盘分割成4个同样大小的子棋盘,然后对每个子棋盘进行递归操作,直到棋盘大小为1。在递归过程中,根据起始位置和目标位置的相对位置,确定在哪个子棋盘内进行覆盖操作。最终,输出的结果为将棋盘覆盖后的情况。 ### 回答3: 棋盘覆盖算法是一常见的分治算法。这个算法基于这样的问题:给定一个2^n × 2^n大小的棋盘,其中有一个单元格缺失,需要用特殊的L型块覆盖整个棋盘。下面是一个简单的算法演示代码: ``` def chessboard_cover(board, tr, tc, dr, dc, size, special_cell): if size <= 1: return tile = special_cell[0] count = special_cell[1] half_size = size // 2 # 标记L型块所在的象限 current_tile = count count += 1 # 左上象限 if dr < tr + half_size and dc < tc + half_size: chessboard_cover(board, tr, tc, dr, dc, half_size, (tile, count)) else: board[tr + half_size - 1][tc + half_size - 1] = current_tile chessboard_cover(board, tr, tc, tr + half_size - 1, tc + half_size - 1, half_size, (tile, count)) # 上象限 if dr < tr + half_size and dc >= tc + half_size: chessboard_cover(board, tr, tc + half_size, dr, dc, half_size, (tile, count)) else: board[tr + half_size - 1][tc + half_size] = current_tile chessboard_cover(board, tr, tc + half_size, tr + half_size - 1, tc + half_size, half_size, (tile, count)) # 左下象限 if dr >= tr + half_size and dc < tc + half_size: chessboard_cover(board, tr + half_size, tc, dr, dc, half_size, (tile, count)) else: board[tr + half_size][tc + half_size - 1] = current_tile chessboard_cover(board, tr + half_size, tc, tr + half_size, tc + half_size - 1, half_size, (tile, count)) # 下象限 if dr >= tr + half_size and dc >= tc + half_size: chessboard_cover(board, tr + half_size, tc + half_size, dr, dc, half_size, (tile, count)) else: board[tr + half_size][tc + half_size] = current_tile chessboard_cover(board, tr + half_size, tc + half_size, tr + half_size, tc + half_size, half_size, (tile, count)) def display_chessboard(board): for row in board: for cell in row: print(str(cell).rjust(2), end=" ") print() # 主函数 def main(): n = 4 # 棋盘大小为2^n × 2^n missing_row = 3 # 缺失单元格的行号 missing_col = 2 # 缺失单元格的列号 board_size = 2 ** n board = [[0] * board_size for _ in range(board_size)] special_cell = (1, 0) # 特殊单元格的L型块编号和当前计数 chessboard_cover(board, 0, 0, missing_row, missing_col, board_size, special_cell) display_chessboard(board) if __name__ == "__main__": main() ``` 这个代码会首先创建一个2^n × 2^n大小的棋盘,并根据给定的缺失单元格的位置,通过递归调用chessboard_cover函数进行覆盖。最后,通过调用display_chessboard函数来展示覆盖后的棋盘。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值