码迷,mamicode.com
首页 > 其他好文 > 详细

UVa 10318 Security Panel

时间:2014-07-19 00:31:44      阅读:278      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   art   

题意:给你一个3*3的翻转模版,深色部分表示翻转,浅色部分不变。然后你可以在r*c的矩形里依照模版进行翻转,要求所有点亮所有块。输出最小的步骤。

思路:有一点比较好想。每个块至多被翻转一次,翻两次的效果是一样的。这样可以搜索,大约2^25,会超时。考虑剪枝。对于每次翻转,只会影响与它临近的几个块,也就是说如果在该块的往上数第2行之前有没亮的块,那么无论之后怎么样,最后一定不会全亮,因为后面的块根本不会影响到前面这些。

这里可以用二进制表示状态。代码写的比较糟乱。

bubuko.com,布布扣
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,ans;
bool ok[10][10];
bool judge(int x,int y)
{
    return 0<=x&&x<n&&0<=y&&y<m;
}
int flip(int state,int p)
{
    bool st[10][10]= {0};
    for(int i=0; i<n*m; ++i)
        if(state&(1<<i)) st[i/m][i%m]=true;
        else st[i/m][i%m]=false;
    int x=p/m,y=p%m;
    if(ok[0][0]&&judge(x-1,y-1)) st[x-1][y-1]=!st[x-1][y-1];
    if(ok[0][1]&&judge(x-1,y)) st[x-1][y]=!st[x-1][y];
    if(ok[0][2]&&judge(x-1,y+1)) st[x-1][y+1]=!st[x-1][y+1];
    if(ok[1][0]&&judge(x,y-1)) st[x][y-1]=!st[x][y-1];
    if(ok[1][1]&&judge(x,y)) st[x][y]=!st[x][y];
    if(ok[1][2]&&judge(x,y+1)) st[x][y+1]=!st[x][y+1];
    if(ok[2][0]&&judge(x+1,y-1)) st[x+1][y-1]=!st[x+1][y-1];
    if(ok[2][1]&&judge(x+1,y)) st[x+1][y]=!st[x+1][y];
    if(ok[2][2]&&judge(x+1,y+1)) st[x+1][y+1]=!st[x+1][y+1];
    int res=0;
    for(int i=0; i<n; ++i)
        for(int j=0; j<m; ++j)
            if(st[i][j]) res=res|(1<<(i*m+j));
    return res;
}
char g[10][10];
int bitcount(int state)
{
    int cnt=0;
    for(int i=0; i<n*m; ++i)
        if(state&(1<<i))
            cnt++;
    return cnt;
}
bool check(int state,int p)
{
    for(int i=0; i<p; ++i)
        if(!(state&(1<<i)))
            return false;
    return true;
}
void dfs(int cur,int state,int use)
{
    if(cur>=n*m)
    {
        if(state==(1<<m*n)-1)
        {
            if(ans==-1||bitcount(use)<bitcount(ans))
                ans=use;
        }
        return ;
    }
    int x=cur/m,y=cur%m;
    if(x>=2&&!check(state,m*(x-1))) return;
    dfs(cur+1,flip(state,cur),use|(1<<cur));
    dfs(cur+1,state,use);
}
int main()
{
    int kase=0;
    while(scanf("%d%d",&n,&m)&&!(!n&&!m))
    {
        ans=-1;
        for(int i=0; i<3; ++i)
        {
            scanf("%s",g[i]);
            for(int j=0; j<3; ++j)
                ok[i][j]=(g[i][j]==*);
        }
        printf("Case #%d\n",++kase);
        dfs(0,0,0);
        if(ans==-1)
            puts("Impossible.");
        else
        {
            bool fir=false;
            for(int i=0; i<n*m; ++i)
                if(ans&(1<<i))
                    if(fir) printf(" %d",i+1);
                    else
                    {
                        fir=true;
                        printf("%d",i+1);
                    }
            printf("\n");
        }
    }
    return 0;
}
/*
5 3
...
***
...
*/
View Code

UVa 10318 Security Panel,布布扣,bubuko.com

UVa 10318 Security Panel

标签:style   blog   http   color   os   art   

原文地址:http://www.cnblogs.com/kkkwjx/p/3853905.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!