• 棋盘问题


    题目网址:http://acm.pku.edu.cn/JudgeOnline/problem?id=1321

    其实就是个神搜的题目,以前做过,但是在拿到题的时候还是会感觉有点我从下手,所以还是多做点就好了吧

    具体思路:
    棋盘问题, 棋子摆放的位置只能是#, 且不能同行和同列. 由于我采用的是按行递增的顺序来搜索的, 因此不可能出现同行的情况, 对于同列的情况, 我设置了一个变量col[], 来保存列的访问状态, 对于之前访问过的列, 棋子是不能再放在这一列上的.
    dfs(begin, num) 代表将第k-num棵棋子放在begin行上, 然后就剩下num-1棵棋子需要放在begin行下面. 当然, 可能存在第num棵棋子根本无法放在begin行上的情况, 对于这种情况, dfs就回溯到上一个dfs调用的地方, 重新开始, 而如果遇到num=1, 且第begin行的一些列可以放的话, 就将方案数相应增加.

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    char ch[10][10];
    
    int visit[10],sum,n;//visit为列的访问状态
    void dfs(int begin,int x)
    {
        for(int j=0;j<n;j++)
            if(ch[begin][j]=='#'&&visit[j]==0)
                if(x==1)
                    sum++;
                else
                {
                    visit[j]=1;
                    for(int w=begin+1;w<=n-(x-1);w++){//条件w<n-(n-1),这是因为如果在比这个大了就一定不成立了,因为之后一行之多一个,从该地址遍历到结束也不会满足x个了  
                    dfs(w,x-1);
                    }
    
                    visit[j]=0;
                }
    }
    int main()
    {
        int x; 
        while(~scanf("%d%d",&n,&x)&&!(n==-1&&x==-1))
        {
            sum=0;
    
            for(int i=0;i<n;i++)
                scanf("%s",ch[i]);
            memset(visit,0,sizeof(visit));
            for(int i=0;i<=n-x;i++) //一共要放x个棋子,每行至多一个,所以需要x行
                dfs(i,x); //从第i行开始,放x个棋子.按照按行递增的顺序访问,一定不会出现同行
            cout<<sum<<endl;
        }
    }
    
    
  • 相关阅读:
    第一次作业
    1-10的四则运算
    实验九
    实验五
    实验四
    实验三
    实验二
    实验一
    汇编第一章总结
    实验九
  • 原文地址:https://www.cnblogs.com/zswbky/p/5432013.html
Copyright © 2020-2023  润新知