• Poj 1321 棋盘问题(搜索)


    Description

    在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。

    Input

    输入含有多组测试数据。
    每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
    当为-1 -1时表示输入结束。
    随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。

    Output

    对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。

    Sample Input

    2 1
    #.
    .#
    4 4
    ...#
    ..#.
    .#..
    #...
    -1 -1
    

    Sample Output

    2
    1
    

    分析:回溯法,这题要求的是方案数量。刚开始的时候就是用二维数组暴搜,但是就是不知道怎么判断这个解是不是重复的,因为棋子没有区别,所以4个位置放4个棋子有24种方法,但是如果棋子相同的话就是一种了。想想每次排序再存起来判断的话会超时,所以就采取了按行(以按行为例)或按列搜索的方法来解。从第一行开始搜索,如果这一行中有满足条件的位置就再搜索下一行,如果这一行没有的话就搜索下下行。再加个判断条件,如果超过N的话就结束,这样到了最后一行,有结果就加一,没有就回溯。有了按按搜索这样一个顺序,再加上判断条件,就不会出现重复的排列了。

    import java.util.Scanner;
    
    public class Main {
    
    	static int N, M;
    	static boolean[][] path;
    	static boolean[] xP;
    	static boolean[] yP;
    	static int ans;
    
    	static void DFS(int row, int n) {
    		if (n == M) {
    			ans++;
    			return;
    		}
    		if (row > N) //配合下面DFS(row+1,num); 语句使用,避免搜索越界
    			return;
    		
    		for (int j = 1; j <= N; j++) {
    			
    			if (path[row][j] && !yP[j] && !xP[row]) {
    				yP[j] = true;
    				xP[row] = true;
    				DFS(row + 1, n + 1);
    				yP[j] = false;
    				xP[row] = false;
    
    			}
    		}
    		DFS(row + 1, n);// 如果该行没有合适的位置,搜索下一行。
    	}
    
    	public static void main(String[] args) {
    		Scanner sc = new Scanner(System.in);
    		while (true) {
    			N = sc.nextInt();
    			M = sc.nextInt();
    			if (N == -1) {
    				break;
    			}
    			String in[] = new String[N + 1];
    
    			path = new boolean[10][10];
    			xP = new boolean[10];
    			yP = new boolean[10];
    			ans = 0;
    			for (int i = 1; i <= N; i++) {
    				in[i] = sc.next();
    				for (int j = 1; j <= N; j++) {
    					if (in[i].charAt(j - 1) == '#') {
    						path[i][j] = true;
    					}
    				}
    			}
    			DFS(0, 0);
    			System.out.println(ans);
    		}
    
    	}
    }
    


    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    主键、外键
    SpringBoot定时任务Scheduled
    启动报DataSource错误
    SpringBoot整合aop
    元数据MetaData(五)
    普通结果集ResultSet和离线结果集RowSet(四)
    Statements、PreparedStatement及CallableStatement(三)
    JDBC数据库连接(二)
    JDBC简介(一)
    【Oracle】常用函数
  • 原文地址:https://www.cnblogs.com/AndyDai/p/4734097.html
Copyright © 2020-2023  润新知