poj 2870 Light Up dfs
题意:在一个n*m的格子里有b个障碍物,每个障碍物都有一个标记表示他的周围(上下左右)必须有且只有几个灯泡,想在让你方灯泡,要求灯泡彼此之间不能被照到,而且每个空白区域一定要被照到,求最少的灯泡数
分析:dfs + 剪枝
View Code
#include <cstdio> #include <cstring> #include <iostream> using namespace std; #define re(i,n) for(int i=0;i<n;i++) #define re1(i,n) for(int i=1;i<=n;i++) #define inf (1<<29) const int maxn = 10; int ans; int map[maxn][maxn]; // -1 to 4:障碍 -2:无障碍 -3:灯 int dir[4][2] = { {0,-1},{0,1},{-1,0},{1,0} }; int R , C , B; int lampNums[maxn][maxn]; bool inMap(int r, int c) { return r>=1 && r<=R && c>=1 && c<=C; } bool _haslamp(int r, int c, int d) { //judge before meeting a barrier whether a lamp while(inMap(r, c)) { if(map[r][c] >= -1 && map[r][c] <= 4) break; else if(map[r][c] == -3) return true; r += dir[d][0]; c += dir[d][1]; } return false; } bool haslamp(int r, int c) { re(i,4) if(_haslamp(r,c,i)) return true; return false; } void SetValue(int r, int c, int num) { re(i,4) { int nr = r + dir[i][0]; int nc = c + dir[i][1]; if(inMap(nr,nc)) lampNums[nr][nc] += num; } } bool Check() { re1(r,R) re1(c,C) { int k = map[r][c]; if(k == -2 && !haslamp(r,c)) return false; else if(k >= 0 && k <= 4) { if(lampNums[r][c] != k) return false; } } return true; } void dfs(int r, int c, int lampnum) { if(r > R) { if(Check() && ans > lampnum) ans = lampnum; return; } if(map[r][c] >= -1 && map[r][c] <= 4) { for(int i=r-1;i>0;i--) { if(map[i][r] == -2 && !haslamp(i,c)) return; else if(map[i][r] >= -1 && map[i][r] <= 4) break; } (c == C ) ? dfs(r+1 , 1 , lampnum) : dfs(r , c+1 , lampnum); } else { if(!haslamp(r, c)) { map[r][c] = -3; SetValue(r, c, 1); (c == C) ? dfs(r+1 , 1, lampnum+1) : dfs(r , c+1, lampnum+1); map[r][c] = -2; SetValue(r , c , -1); (c == C) ? dfs(r+1 , 1 , lampnum) : dfs(r , c+1 , lampnum); } else (c == C) ? dfs(r+1, 1 , lampnum) : dfs(r , c+1 , lampnum); } } void init() { ans = inf; re1(r,R) re1(c,C) map[r][c] = -2 , lampNums[r][c] = 0; } int main() { int r , c , v; while(~scanf("%d%d",&R,&C) && R) { init(); scanf("%d",&B); re(i,B) { scanf("%d%d%d",&r,&c,&v); map[r][c] = v; } dfs(1 , 1 , 0); (ans==inf) ? printf("No solution\n") : printf("%d\n",ans); } return 0; }