HDOJ 1045 Fire Net (贪心)

贪心思路:

     先预处理出h[i][j]数组,表示(i,j)位置的点到最近的‘x’的距离

     然后从上到下,从左到右遍历:

     每一行取h[i][j]最小的点放置(对后面结果影响最小,同时vis[j]==0可放置),放置后vis[j]置1。

     当遇到‘x'时,清零该位置vis[j]值,同时重新取之后的h[i][j]最小的点即可

 

#include<iostream>
#include<fstream>
#include<cstdlib>
#include<iomanip>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>

#define REP(i,l,r) for(int i=(l);i<=(r);++i)
#define REP2(i,l,r) for(int i=(l);i>=(r);--i)
#define CLR(a,v) memset(a,v,sizeof(a))
#define sqr(x) ((x)*(x))
#define SCAN(n) scanf("%d",&n)
#define SCAN2(n,m) scanf("%d %d",&n,&m)
#define SCANS(s) scanf("%s",s);
#define PRINT(n) printf("%d\n",n)

using namespace std;

typedef long long ll;

const int INF=1e9;
const int MOD=(int)1e9+7;
const int N=100010;

/*------------------------------------------------------------------------*/

int h[5][5];
int vis[5];
char s[10];

int main(){
    int n;
    while(SCAN(n)!=EOF&&n){
        CLR(h,0);
        REP(i,1,n){
            SCANS(s+1);
            REP(j,1,n)
                if(s[j]=='.') h[i][j]=1;
                else h[i][j]=0;
        }
        REP2(i,n-1,1)
            REP(j,1,n){
                if(h[i][j]) h[i][j]+=h[i+1][j];
        }
        int ans=0;
        CLR(vis,0);
        REP(i,1,n){
            int cnt=5,p=0;
            REP(j,1,n+1){
                if(!vis[j]&&h[i][j]&&h[i][j]<cnt){
                    cnt=h[i][j];
                    p=j;
                }
                if(!h[i][j]){
                    if(cnt<5){
                        ++ans;
                        vis[p]=1;
                        cnt=5;
                    }
                    vis[j]=0;
                }
            }
        }
        PRINT(ans);
    }
    return 0;
}

 

posted @ 2013-07-07 14:11  parryworld  阅读(239)  评论(0编辑  收藏  举报