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;
}
posted @ 2012-07-01 23:27  lenohoo  阅读(422)  评论(0编辑  收藏  举报