当前位置: 代码迷 >> 综合 >> [kuangbin带你飞]专题一 简单搜索 POJ - 1321
  详细解决方案

[kuangbin带你飞]专题一 简单搜索 POJ - 1321

热度:41   发布时间:2024-01-09 12:16:57.0

题目:

棋盘问题
Time Limit: 1000MS		Memory Limit: 10000K
Total Submissions: 56854		Accepted: 27377
Description在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
Input输入含有多组测试数据。 
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n 
当为-1 -1时表示输入结束。 
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。 
Output对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
Sample Input2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1
Sample Output2
1
Source蔡错@pku

题解:

这道题目其实有点类似八皇后问题,但是和八皇后问题有一点点不同,那就是八皇后问题每行必须要放置棋子,但是这道题目却没有这个必要。
所以这就要写两个递归,类似于二叉树,放置或者不放置。
需要注意的一点是,写递归的题目一定要保证返回条件,最好将每一个条件单独写一个条件语句,这道提就是因为没有区分好条件语句导致超时。
后来把返回的条件语句区分好之后就正常运行了。

Code:

#ifdef local
#include    <ctime>
#endif
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>
#define rep(i,e) for(int i=0;i<e;i++)
#define rep1(i,e) for(int i=1;i<=e;i++)
#define repx(i,x,e) for(int i=x;i<=e;i++)
#define ll long long
#define pii pair<int,int>
#define F first
#define S second
#define pb push_back
#define mp make_pair
#define mset(var,val) memset(var,val,sizeof(var))
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define test(a) cout<<a<<endl
#define test2(a,b) cout<<a<<" "<<b<<endl
#define test3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl
typedef unsigned long long ull;
using namespace std;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int inf = 0x3f3f3f3f;
const int N = 2e6 + 10;
int m[50][50];
int vis1[50];
char ch[50];
int  n;
int ans = 0;int tt[50];
void solove(int cur, int num) {if (num == 0){ans++;return ;}if (cur >=n )return;for (int i = 0; i < n; i++) {if (m[cur][i]) {if (!vis1[i]) {vis1[i] = 1;solove(cur + 1, num - 1);vis1[i] = 0;}}}solove(cur + 1, num);
}
void work() {int k;while (1) {scdd(n, k);ans = 0;mset(vis1, 0);mset(m,0);if (n == -1 && k == -1)return;for (int i = 0; i < n; i++) {scanf("%s", ch);for (int j = 0; j < n; j++) {if (ch[j] == '#') {m[i][j] = 1;}}}solove(0, k);printf("%d\n", ans);}
}
int main() {
#ifdef localfreopen("in.txt", "r", stdin);freopen("out", "w", stdout);clock_t t_begin = clock();
#endifwork();
#ifdef localclock_t t_end = clock();double time = (t_end - t_begin) / (double)(CLOCKS_PER_SEC);printf("\n\n\nTime_used=%.10lf", time);
#endif}