4770 Lights Against Dudely

暴力枚舉



#include<iostream>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define INF (1<<30)
struct Point
{
    int x,y;
    void get(int xx,int yy)
    {
        x=xx;
        y=yy;
    }
}p[20];
struct Num 
{
    int oneNum,pos;
}num[1<<20];
int cnt;
int ans;
int n,m;
char map[220][220];
int bri[220][220];
int dir1[4][2]={-1,0, 1,0, 1, 0, -1,0};
int dir2[4][2]={ 0,1, 0,1, 0,-1, 0,-1};
bool cmp(Num a,Num b)
{
    return a.oneNum<=b.oneNum;
}
int getNum(int x)
{
    int num=0;
    while(x)
    {
        num++;
        x&=x-1;
    }
    return num;
}
int judge(int i,int d)
{
    int tx=p[i].x+dir1[d][0],ty=p[i].y+dir1[d][1];
    int ttx=p[i].x+dir2[d][0],tty=p[i].y+dir2[d][1];
    if(tx>=0&&tx<n&&ty>=0&&ty<m&&map[tx][ty]=='#')
        return 0;
    if(ttx>=0&&ttx<n&&tty>=0&&tty<m&&map[ttx][tty]=='#')
        return 0;
    return 1;
}
void add(int i,int d,int& num)
{
    int tx=p[i].x+dir1[d][0],ty=p[i].y+dir1[d][1];
    int ttx=p[i].x+dir2[d][0],tty=p[i].y+dir2[d][1];
    if(bri[p[i].x][p[i].y]==0)
        num++;
    bri[p[i].x][p[i].y]++;
    if(tx>=0&&tx<n&&ty>=0&&ty<m)
    {
        if(bri[tx][ty]==0)
            num++;
        bri[tx][ty]++;
    }        
    if(ttx>=0&&ttx<n&&tty>=0&&tty<m)
    {
        if(bri[ttx][tty]==0)
            num++;
        bri[ttx][tty]++;
    }
    
}
void sub(int i,int d,int& num)
{
    int tx=p[i].x+dir1[d][0],ty=p[i].y+dir1[d][1];
    int ttx=p[i].x+dir2[d][0],tty=p[i].y+dir2[d][1];
    bri[p[i].x][p[i].y]--;
    if(bri[p[i].x][p[i].y]==0)
        num--;
    if(tx>=0&&tx<n&&ty>=0&&ty<m)
    {
        bri[tx][ty]--;
        if(bri[tx][ty]==0)
            num--;
    }
        
    if(ttx>=0&&ttx<n&&tty>=0&&tty<m)
    {
        bri[ttx][tty]--;
        if(bri[ttx][tty]==0)
            num--;
    }
        
}
int solve(int S,int k)
{
    int num=0;
    for(int i=0;i<cnt;i++)
    {
        if(i==k)
            continue;
        if(S&(1<<i))
        {
            if(judge(i,0))
                add(i,0,num);
            else
                return 0;
        }
    }
    for(int i=0;i<4;i++)
        if(judge(k,i))
        {
            add(k,i,num);
            if(num==cnt)
                return 1;
            sub(k,i,num);
        }
    return 0;
}
int main()
{
    while(cin>>n>>m&&n+m)
    {
    	cnt=0;
        for(int i=0;i<n;i++)
        {
            scanf("%s",map[i]);
            for(int j=0;j<m;j++)
                if(map[i][j]=='.')
                    p[cnt++].get(i,j);
        }
        if(cnt==0)
        {
            cout<<0<<endl;
            continue;
        }
        for(int i=0;i<(1<<cnt);i++)
        {
            num[i].pos=i;
            num[i].oneNum=getNum(i);
        }
        sort(num,num+(1<<cnt),cmp);
        ans=INF;
        int flag=0;
        for(int r=0;r<(1<<cnt)&&flag==0;r++)
        {
            int i=num[r].pos;
            for(int j=0;j<cnt;j++)
            {
                if(i&(1<<j))
                {
                    for(int f=0;f<cnt;f++)
                        bri[p[f].x][p[f].y]=0;
                    if(solve(i,j))
                    {
                        ans=min(ans,num[r].oneNum);
   						flag=1;
   						break;
                    }                
                }
            }
        }
        if(ans>=INF)
            cout<<-1<<endl;
        else
            cout<<ans<<endl;
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章