• POJ 1321 棋盘问题(C)回溯


    Emmm,我又来 POJ 了,这题感觉比上次做的简单点。类似皇后问题。但是稍微做了一点变形,比如棋子数量是不定的。棋盘形状不在是方形等等。

    题目链接:POJ 1321 棋盘问题


    解题思路

    基本思路:从上往下放旗子,每种情况完成后,复盘继续下一种情况。

    这里讲一下,void backTrack(int left, int x) 函数。

    left 表示还剩的棋子数量,显然如果 left 为 0,说明所有棋子已放完,那么方案数 solution 加 1。

    如果不为 0。那么继续检查当前位置的列是否有棋子,如果无棋子,那么当前位置可以放旗子。然后继续递归,棋子数量减 1,行数加 1。如果有棋子,那么悔棋 1 步。继续下一个位置。

    C代码

    /**
     *	@author wowpH
     *	@date 2019-9-14 19:54:16
     */
    #include<stdio.h>
    #include<string.h>
    
    #define TRUE 1
    #define FALSE 0
    
    #define MAX_N 8		// 矩阵最大为8
    
    #define BOARD TRUE		// 棋盘
    #define BLANK FALSE		// 空白
    
    int matrix[MAX_N][MAX_N];// 矩阵,BOARD表示棋盘,BLANK表示空白
    
    int n, k, solution;// solution最终结果
    
    int column[MAX_N];// 每列是否有棋子,TRUE表示有棋子,FALSE表示无棋子
    
    void backTrack(int left, int x) {// 回溯,left表示剩余棋子,x表示当前行
    	if (left == 0) {// 无多余棋子
    		++solution;	// 方案数加1
    		return;
    	}
    
    	// 遍历x行及下方的棋盘
    	for (int i = x; i < n; ++i) {
    		for (int j = 0; j < n; ++j) {
    			if (matrix[i][j] == BLANK) {// 空白
    				continue;				// 不能放旗子
    			}
    			if (column[j] == TRUE) {// 第j列有棋子
    				continue;			// 不能放旗子
    			}
    
    			column[j] = TRUE;			// 当前位置可以放子,设为TRUE
    			backTrack(left - 1, i + 1);	// 回溯,棋子数减1,行数加1
    			column[j] = FALSE;			// 复盘,设为无子
    		}
    	}
    }
    
    int main() {
    	while (scanf("%d %d", &n, &k) && n != -1 && k != -1) {
    		getchar();// '
    '
    
    		// 输入棋盘
    		for (int i = 0; i < n; ++i) {
    			for (int j = 0; j < n; ++j) {
    				char ch = getchar();
    				if (ch == '.') {
    					matrix[i][j] = BLANK;// 空白
    				} else if (ch == '#') {
    					matrix[i][j] = BOARD;// 棋盘
    				}
    			}
    			getchar();// '
    '
    		}
    
    		// 初始化
    		memset(column, FALSE, sizeof(column));
    		solution = 0;
    
    		backTrack(k, 0);// 回溯
    
    		printf("%d
    ", solution);
    	}
    	return 0;
    }
    

    提交结果

    在这里插入图片描述

  • 相关阅读:
    最长回文子串 leetcode
    leetcode Plus one
    n的阶乘末尾有几个0?
    求两数的最大公约数和最小公倍数
    汉诺塔
    求n的阶乘
    svn book
    求斐波那契数列第n项
    判断一个数是否是素数
    <C Traps and Pitfalls>笔记
  • 原文地址:https://www.cnblogs.com/wowpH/p/11687395.html
Copyright © 2020-2023  润新知