HDUOJ 1045 Fire Net

#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;
}
//不知道该以什么样的方式来搜索,每走一步再往上下左右?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值