J - 棋盘问题

Posted wgd943

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了J - 棋盘问题相关的知识,希望对你有一定的参考价值。

作为新手的我,看到该题很自然的没想到用搜索。。。通过大佬的讲解才有了个大体思想

【题意】给你一个棋盘nxm的,然后你的棋子只能放在有‘#’的位置,当然棋子的个数是自己定的,棋盘可放棋子的个数也是自己决定的。最后问棋子放在可用棋盘上的方案数。

【思路】由于要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列。所以可以一行一行的找,从第一行开始,找到‘#’对其标记,从下一行开始找;代码过程中需要对同行同列的‘#’进行标记。

代码:

技术图片
#include<stdio.h>
#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
 
char a[8][8];
int vis[8];//仅记录某一行是否有棋子 
int n,k;
int sum;

//dfs常用套路
void dfs(int x,int y){
    
    if(y==k){//判断边界 
        sum++;
        return ;
        //printf("%d-----
",sum);     
    }
    if(x>=n)  return ; 
     for (int i = x; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (!vis[j] && a[i][j] == #) //棋子只能在可用的棋盘区域
            {
                vis[j] = 1;//标记本行的这一列不能在有棋子了
                dfs(i + 1, y + 1);//递归,进行下一行的计算
                vis[j] = 0;//结束了,本行位置没有棋子了
            }
        }
    }
    return ;
}

int main(){
    while(cin>>n>>k)
    {
        
        sum=0;
        memset(vis,0,sizeof(vis));
        memset(a,0,sizeof(a));
        if(n==-1&&k==-1)
        break;
    for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
    {cin>>a[i][j];
    }
    dfs(0,0);
    cout<<sum<<"
";
    }
    return 0;
}
View Code

【注意】此题虽然很有dfs的模板,但是我觉得主要是标记的时候,只标记了该列的,走过该列后再标记为0;

且每次递归到达相应的总棋子数才会加一到下一行;其实也是回溯的方式

。。。。我都不知道我说了什么。

以上是关于J - 棋盘问题的主要内容,如果未能解决你的问题,请参考以下文章

J - 棋盘问题

Python算法题——国际象棋棋盘(排列组合问题,最小的K个数)

题目:要求输出国际象棋棋盘。 printf("%c%c",219,219);啥意思???

洛谷 P1169 [ZJOI2007]棋盘制作

ZJOI2007棋盘制作[动规 悬线法]

五子棋