HDU 4770 Lights Against Dudely(暴力)

HDU 4770 Lights Against Dudely

题目链接

题意:给定灯,有一盏灯可以旋转,问最少几个灯可以照亮.的位置,并且不能照到#

思路:暴力求解,先枚举特殊的灯,再枚举正常的灯,要加剪枝,不然会TLE

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 205;
const int d[4][3][2] = {{{0, 0}, {-1, 0}, {0, 1}},
			{{0, 0}, {1, 0}, {0, 1}},
			{{0, 0}, {1, 0}, {0, -1}},
			{{0, 0}, {-1, 0}, {0, -1}}};

int n, m, g[N][N], x[N], y[N], pn, light[N][N], put[N][N], ans;
char str[N];

bool judge(int x, int y, const int d[][2], int &ans) {
    if (put[x][y]) return false;
    ans = 0;
    for (int i = 0; i < 3; i++) {
	int xx = x + d[i][0];
	int yy = y + d[i][1];
	if (xx > n || xx < 1 || yy > m || yy < 1) continue;
	if (!g[xx][yy]) return false;
    }
    for (int i = 0; i < 3; i++) {
	int xx = x + d[i][0];
	int yy = y + d[i][1];
	if (xx > n || xx < 1 || yy > m || yy < 1) continue;
	if (light[xx][yy] == 0) ans++;
	light[xx][yy]++;
    }
    return true;
}

bool judge2(int now) {
    for (int i = 0; i < pn; i++) {
	if (x[i] <= now) break;
	if (!light[x[i]][y[i]]) return false;
    }
    return true;
}

int dfs(int now, int li, int num) {
    if (num > ans) return INF;
    if (!judge2(x[now])) return INF;
    if (li == 0) return num;
    if (now == pn) return INF;
    int tmp;
    int ans = INF;
    if (judge(x[now], y[now], d[0], tmp)) {
	ans = min(ans, dfs(now + 1, li - tmp, num + 1));
	for (int i = 0; i < 3; i++) {
	    int xx = x[now] + d[0][i][0];
	    int yy = y[now] + d[0][i][1];
	    if (xx > n || xx < 1 || yy > m || yy < 1) continue;
	    light[xx][yy]--;
	}
    }
    ans = min(ans, dfs(now + 1, li, num));
    return ans;
}

int main() {
    while (~scanf("%d%d", &n, &m) && n || m) {
	for (int i = 1; i <= n; i++) {
	    scanf("%s", str + 1);
	    for (int j = 1; j <= m; j++)
		g[i][j] = (str[j] == '.'?1:0);
	}
	pn = 0;
	for (int i = n; i >= 1; i--) {
	    for (int j = 1; j <= m; j++) {
		if (g[i][j]) {
		    x[pn] = i;
		    y[pn] = j;
		    pn++;
		}
	    }
	}
	memset(light, 0, sizeof(light));
	ans = INF;
	ans = dfs(0, pn, 0);
	for (int i = 0; i < pn; i++) {
	    for (int j = 0; j < 4; j++) {
		int tmp = 0;
		memset(light, 0, sizeof(light));
		if (judge(x[i], y[i], d[j], tmp)) {
		    put[x[i]][y[i]] = 1;
		    ans = min(ans, dfs(0, pn - tmp, 1));
		    put[x[i]][y[i]] = 0;
		}
	    }
	}
	if (ans == INF) printf("-1\n");
	else printf("%d\n", ans);
    }
    return 0;
}

HDU 4770 Lights Against Dudely(暴力)

时间: 2024-10-11 22:50:00

HDU 4770 Lights Against Dudely(暴力)的相关文章

HDU 4770 Lights Against Dudely 暴力枚举+dfs

又一发吐血ac,,,再次明白了用函数(代码重用)和思路清晰的重要性. 11779687 2014-10-02 20:57:53 Accepted 4770 0MS 496K 2976 B G++ czy Lights Against Dudely Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1360    Accepted Subm

hdu 4770 Lights Against Dudely 暴力搜索

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4770 题目大意是让你放一些灯照亮一些房间 灯不可以照到某些特殊房间 但可以照出边界 灯光必须覆盖所有可以放灯的房间 求至少需要多少灯 搜索题 应该注意到冗长而无聊的题面中有告诉你最多只有15个可以放灯的房间 所以2^15来枚举 还应该注意到冗长而无聊的题面中有告诉你最多只有1个灯可以转向 所以还应该枚举哪个灯来转向 转向再枚举4个方向 然后判断是否成立 为了简化问题 单独把那些可放灯空间拿出来 最多

hdu 4770 Lights Against Dudely(回溯)

题目链接:hdu 4770 Lights Against Dudely 题目大意:在一个N*M的银行里,有N*M个房间,'#'代表坚固的房间,'.'代表的是脆弱的房间,脆弱的房间个数不会超过15个,现在为了确保安全,要在若干个脆弱的房间上装灯,普通的灯是照亮{0, 0}, {-1, 0}, {0, 1}(和题目中坐标有点出入),然后可以装一个特殊的,可以照射 { {0, 0}, {0, 1}, {1, 0} }, { {0, 0}, {-1, 0}, {0, -1} }, { {0, 0}, {

HDU 4770 Lights Against Dudely

Problem Description Harry: "But Hagrid. How am I going to pay for all of this? I haven't any money." Hagrid: "Well there's your money, Harry! Gringotts, the wizard bank! Ain't no safer place. Not one. Except perhaps Hogwarts." - Rubeus

hdu 4770 13 杭州 现场 A - Lights Against Dudely 暴力 bfs

Description Harry: "But Hagrid. How am I going to pay for all of this? I haven't any money." Hagrid: "Well there's your money, Harry! Gringotts, the wizard bank! Ain't no safer place. Not one. Except perhaps Hogwarts." ― Rubeus Hagrid

状态压缩 + 暴力 HDOJ 4770 Lights Against Dudely

题目传送门 题意:有n*m的房间,'.'表示可以被点亮,'#'表示不能被点亮,每点亮一个房间会使旁边的房间也点亮,有意盏特别的灯可以选择周围不同方向的房间点亮.问最少需要多少灯使得所有房间点亮 分析:需要被点亮的房间最多只有15个,所以考虑状压,然后暴力枚举选择哪一个当作特殊灯和枚举选择哪个方向使旁边的房间亮,注意清空vis数组需要优化,memset超时.上交6分钟1Y,Orz... /************************************************ * Auth

HDU 4770 状压暴力枚举

Lights Against Dudely Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1415    Accepted Submission(s): 412 Problem Description Harry: "But Hagrid. How am I going to pay for all of this? I haven't

HDU 4930 Fighting the Landlords(暴力枚举+模拟)

HDU 4930 Fighting the Landlords 题目链接 题意:就是题中那几种牌型,如果先手能一步走完,或者一步让后手无法管上,就赢 思路:先枚举出两个人所有可能的牌型的最大值,然后再去判断即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct Player { int rank[15]; } p1, p2; int t, h

hdu 1399 Starship Hakodate-maru (暴力搜索)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1399 题目大意:找到满足i*i*i+j*(j+1)*(j+2)/6形式且小于等于n的最大值. 1 #include<iostream> 2 #include<cstdio> 3 4 using namespace std; 5 6 int main() 7 { 8 int n; 9 while(scanf("%d",&n),n) 10 { 11 int j,