POJ - 1321 棋盘问题 n皇后问题(二进制版本)

题目大意:给出一个n * n的棋盘,这个棋盘上面有些地方不能放棋子。

现在要求你在这个棋盘上面放置k个棋子,使得这些棋子的任意两个不在同行同列上,问有多少种方法

解题思路:类似n皇后的问题,可以一行一行的处理,用二进制的1表示该位置可放,0表示不可放,All表示每行能放的状态( (1 << n) - 1)

假设列的状态是s,那么 s & (该行的限制) & All就是该行的终态了.

现在只要找到这个终态的所有1就可以了,那么怎么快速的找到这个1

假设终态是ss,那么ss & (-ss) & All就是第一个1的位置了(可自行验证),然后设一个while循环就可以找到所有的1了,记得&All

#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 20;
char str[N];
int n, k, ans, All, statu[N];

void init() {

    All = (1 << n) - 1;
    for(int i = 0; i < n; i++) {
        gets(str);
        statu[i] = All;
        for(int j = 0; j < n; j++)
            if(str[j] == ‘.‘)
                statu[i] ^= (1 << j);
    }
    ans = 0;
}

void solve(int cur, int num, int s) {
    if(num == k) {
        ans++;
        return ;
    }

    if(cur == n || n - cur + num < k)
        return ;
    int ss = (s & statu[cur]) & All;
    while(ss) {
        int t = ss & (-ss) & All;
        solve(cur + 1, num + 1, s ^ t);
        ss = (ss ^ t )& All;
    }
    solve(cur + 1, num, s);
}

int main() {
    while(gets(str)) {
        sscanf(str,"%d%d", &n, &k);
        if(n == -1 && k == -1)
            break;
        init();
        solve(0,0,All);
        printf("%d\n", ans);
    }
    return 0;
}
时间: 2024-11-06 00:49:48

POJ - 1321 棋盘问题 n皇后问题(二进制版本)的相关文章

POJ 1321 棋盘问题 --- DFS

POJ 1321 棋盘问题 http://poj.org/problem?id=1321 /*POJ 1321 棋盘问题 --- DFS*/ #include <cstdio> #include <cstring> int n, k, cnt; bool visit[10]; //标记列的访问状态 char mapp[10][10]; /*从第r行开始正确放置p个棋子*/ void dfs(int r, int p){ if (p == 0){ ++cnt; return; } i

POJ 1321 棋盘问题(搜索)

题目链接:POJ 1321 棋盘问题 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 28825   Accepted: 14276 Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C. Input 输入含有多组测试数据. 每组数据的第一行是两个正整数,

poj 1321 棋盘问题 【DFS】

题意:... 策略:深搜. 仔细分析我们发现,我们只需要对列进行标记,对于行我们考虑放棋子还是不放就行了. 代码: #include<stdio.h> #include<string.h> char s[10][10]; int n, m; int vis[10]; int ans; void dfs(int cur, int step) { if(step == m){ ans ++; return; } if(cur > n-1) return ; int i, j; f

DFS POJ 1321 棋盘问题

题目传送门 1 /* 2 DFS:因为一行或一列都只放一个,可以枚举从哪一行开始放,DFS放棋子,同一列只能有一个 3 */ 4 #include <cstdio> 5 #include <algorithm> 6 #include <cstring> 7 using namespace std; 8 9 char maze[10][10]; 10 bool vis[10]; 11 int n, k, ans; 12 13 void DFS(int x, int num

POJ 1321 棋盘问题(dfs回溯)

A - 棋盘问题 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1321 Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C. Input 输入含有多组测试数据. 每

POJ 1321 棋盘问题(dfs八皇后变形)

棋盘问题 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 25147   Accepted: 12424 Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C. Input 输入含有多组测试数据. 每组数据的第一行是两个正整数,n k,用一个空格隔开,表示

Poj 1321 棋盘问题 【回溯、类N皇后】

棋盘问题 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 27749   Accepted: 13710 Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C. Input 输入含有多组测试数据. 每组数据的第一行是两个正整数,n k,用一个空格隔开,表示

poj 1321 棋盘问题 (简单的DFS)

棋盘问题 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26726   Accepted: 13242 Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C. Input 输入含有多组测试数据. 每组数据的第一行是两个正整数,n k,用一个空格隔开,表示

POJ - 1321 棋盘问题(简单搜索)

题意:在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C. 分析: 1.和八皇后很相似,一行一行的放,并判断该列是否放过. 2.唯一注意的是,因为要摆放的棋子数k可能小于棋盘的行数,所以不一定是从第一行开始放的,所以每行的情况都要搜一下. #include<cstdio> #include<cstring> #include<cs