UVA 639

来源:互联网 发布:手机应用隐藏软件 编辑:程序博客网 时间:2024/06/16 17:35

题目大意:棋盘上放棋子,要求这颗棋子的上下左右不能有其他棋子,两枚棋子之间有墙隔开,则可以。给定棋盘,问最多可以放几枚棋子。

解题思路:生成子集的构造法,将所有情况枚举,然后判断是否成立,最大4*4的棋盘。2^16可以的。

ac代码:

#include <iostream>#include <cstring>#include <algorithm>using namespace std;int n, re, a[20], x[10], y[10], flag;char puz[10][10];void jud(int x, int a, int b, int c){flag = 0;if (c){for (int k=b+1; k<a; k++)if (puz[k][x] == 'X')flag = 1;}elsefor (int k=b+1; k<a; k++)if (puz[x][k] == 'X')flag = 1;}int check(int cur){for (int i=0; i<cur; i++){x[i] = a[i] / n, y[i] = a[i] % n;if (puz[ x[i] ][ y[i] ] == 'X')return 0;}for (int i=0; i<cur; i++)for (int j=i+1; j<cur; j++)if (x[i] == x[j]){if (y[i] > y[j])jud(x[i], y[i], y[j], 0);elsejud(x[i], y[j], y[i], 0);if (!flag)return 0;}else if (y[i] == y[j]){if (x[i] > x[j])jud(y[i], x[i], x[j], 1);elsejud(y[i], x[j], x[i], 1);if (!flag)return 0;}return cur;}void dfs(int cur){int minu=0;if (cur > re)re = max(re, check(cur));if (cur)minu = a[cur-1] + 1;for (int i=minu; i<n*n; i++){a[cur] = i;dfs(cur+1);}}int main(){while (scanf("%d", &n)!=EOF && n){for (int i=0; i<n; i++)scanf("%s", puz[i]);re = 0;dfs(0);printf("%d\n", re);                                                         }return 0; }