#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <sstream>
#include <utility>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <cctype>
#define CLEAR(a, b) memset(a, b, sizeof(a))
#define IN() freopen("in.txt", "r", stdin)
#define OUT() freopen("out.txt", "w", stdout)
#define PF(a) printf("%d\n", a)
#define SF(a) scanf("%d", &a)
#define SFF(a, b) scanf("%d%d", &a, &b)
#define FOR(i, a, b) for(int i = a; i < b; ++i)
#define LL long long
#define maxn 10
#define mod 1000007
#define INF 1000005
using namespace std;
//------------------------------------------------------------------------------------------//
//其实想法上倒也没错啦,,就是枚举次数,大于n*n退出,好弱啊,水题都a不了
//看了别人的代码,我能看出来,这是紫书上给的八数码的方法,同样是看紫书,我为什么领悟不了呢。。。
//这个方法思路蛮清晰的诶
int n;
char a[maxn][maxn];
int ans, cnt;
bool check(int x, int y) {
bool ok = true;
if (a[x][y] == 'X' || a[x][y] == '1') return false;
int t = x;
while (t - 1 >= 0 && a[t - 1][y] != 'X') {
t--;
if (a[t][y] == '1') return false;
}
t = y;
while (t - 1 >= 0 && a[x][t - 1] != 'X') {
t--;
if (a[x][t] == '1') return false;
}
t = x;
while (t + 1 < n && a[t + 1][y] != 'X') {
t++;
if (a[t][y] == '1') return false;
}
t = y;
while (t + 1 < n && a[x][t + 1] != 'X') {
t++;
if (a[x][t] == '1') return false;
}
return true;
}
void dfs() {
ans = max(ans, cnt);//访问时更新最值
//printf("ans = %d\n", ans);
FOR(i, 0, n) FOR(j, 0, n) {
if (check(i, j)) {
a[i][j] = '1', cnt++;
dfs();//从这进入一个分支
a[i][j] = '.', cnt--;
}
}
}
int main() {
//IN(); OUT();
while (SF(n) && n) {
ans = cnt = 0;//记录次数与最值
FOR(i, 0, n) scanf("%s", a[i]);
dfs(); PF(ans);
}
return 0;
}
//写了个二进制法,,自己举了十几个样例都能过,,还是WA诶,,伤感。我要去参考下别人的代码了额
int n;
char a[maxn][maxn];
vector<int> ans;
int temp[4][4];
bool phase(int x, int y) {
if (a[x][y] == 'X') return false;
int t = x;
while (t - 1 >= 0 && a[t - 1][y] != 'X') {
t--;
if (temp[t][y] == 1) return false;
}
t = y;
while (t - 1 >= 0 && a[x][t - 1] != 'X') {
t--;
if (temp[x][t] == 1) return false;
}
t = x;
while (t + 1 < n && a[t + 1][y] != 'X') {
t++;
if (temp[t][y] == 1) return false;
}
t = y;
while (t + 1 < n && a[x][t + 1] != 'X') {
t++;
if (temp[x][t + 1] == 1) return false;
}
return true;
}
bool judge() {
FOR(i, 0, n) FOR(j, 0, n) {
if (temp[i][j] == 1) {
if (!phase(i, j)) return false;
}
}
return true;
}
int check(int x) {
int ret = 0;
FOR(i, 0, n) FOR(j, 0, n) {
if (x & (1<<(i*n + j))) {
temp[i][j] = 1, ret++;
//printf("ret = %d\n", ret);
}
else temp[i][j] = 0;
if (i && j) {
if (temp[i][j]) {
if (temp[i][j - 1] || temp[i - 1][j]) return 0;
}
}
}
if (judge()) return ret;
else return 0;
}
int main() {
//IN(); OUT();
while (SF(n) && n) {
ans.clear(); CLEAR(temp, 0);
FOR(i, 0, n) scanf("%s", a[i]);
ans.push_back(0);
for (int i = 0; i < (1 << (n*n)); ++i) {
ans.push_back(check(i));
}
sort(ans.begin(), ans.end());
cout << ans.back() << endl;
}
return 0;
}
//错误想法
int n;
int d[][2] = { {1, 0}, {0, 1} };
int vis[maxn][maxn];
char a[maxn][maxn];
bool check(int x, int y) {
bool ok = true;
if (x < 0 || x >= n || y < 0 || y >= n || a[x][y] == 'X' || vis[x][y] == 1) return false;
}
bool ok(int x, int y) {
int t = x;
while (t - 1 >= 0 && a[t - 1][y] != 'X') {
t--;
if (a[t][y] == '1') return false;
}
t = y;
while (t - 1 >= 0 && a[x][t - 1] != 'X') {
t--;
if (a[x][t] == '1') return false;
}
t = x;
while (t + 1 < n && a[t + 1][y] != 'X') {
t++;
if (a[t][y] == '1') return false;
}
t = y;
while (t + 1 < n && a[x][t + 1] != 'X') {
t++;
if (a[x][t + 1] == '1') return false;
}
return true;
}
int dfs(int x, int y, int c) {
int cnt = 0, r1 = 1, r2 = 0;
FOR(i, 0, 2) {
if (check(x + d[i][0], y + d[i][1])) {
c + 1;
vis[x][y] = 1;
r1 += dfs(x + d[i][0], y + d[i][1], c);
vis[x][y] = 0;
r2 += dfs(x + d[i][0], y + d[i][1], c);
}
}
cnt = max(r1, r2);
return cnt;
}
int main() {
IN(); OUT();
while (SF(n) && n) {
CLEAR(vis, 0);
FOR(i, 0, n) scanf("%s", a[i]);
PF(dfs(0, 0, 0));
}
return 0;
}
//不知道该以什么样的方式来搜索,每走一步再往上下左右?
HDUOJ 1045 Fire Net
最新推荐文章于 2021-01-14 22:06:16 发布