poj 1321棋盘问题

来源:互联网 发布:自然哲理 知乎 编辑:程序博客网 时间:2024/05/29 18:39
棋盘问题
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 21061 Accepted: 10458

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

21

Source

蔡错@pku

本题dfs,难度不大,但会超时。。。很像八皇后问题,一开始想偷懒只用了表示一个位置的个数的变量做为dfs参数,结果贡献一次TLE。。。后来加了一个表示棋子个数的参数做为dfs参数就过了。真是不作死就不会死。。。

#include<algorithm>#include<iostream>#include<cstdio>#include<cstring>using namespace std;char Map[10][10];bool vis_x[10];///表示该行有没有被占用bool vis_y[10];///表示该列有没有被占用bool used[100];///表示这个棋子有没有被用过。int ans;struct node{    int x;    int y;};node put[100];int n , k , t;///t表示有多少个位置可以放棋子。void dfs(int num , int x)///表示第num个棋子,放在第x个可以放棋子的位置上,两个参数控制,能够节省不少时间。{    if(num >= k)    {        ans++;        return;    }    for(int i=x; i<t; ++i)    {        if(!vis_x[put[i].x] && !vis_y[put[i].y] && !used[i])        {            vis_x[put[i].x] = 1;            vis_y[put[i].y] = 1;            used[i] = 1;///标记该行,该列,该棋子已经用过。            dfs(num + 1 , i + 1);            vis_x[put[i].x] = 0;            vis_y[put[i].y] = 0;            used[i] = 0;        }    }}int main(){    while(scanf("%d%d", &n, &k) != EOF)    {        if(n == -1 && k == -1) break;        getchar();        t = 0;///表示可以放棋子的位置的个数        for(int i=0; i<n; ++i)        {            for(int j=0; j<n; ++j)            {                scanf("%c", &Map[i][j]);                if(Map[i][j] == '#')                {                    put[t].x = i;                    put[t++].y = j;///记录每一个可以放棋子的位置的坐标。                }            }            getchar();        }        ans = 0;        dfs(0 , 0);        printf("%d\n", ans);    }    return 0;}


0 0
原创粉丝点击