POJ 3279 搜索

给出最高15*15的0 1矩阵,每次可以翻转一个点,其相邻的4个点都被翻转,问最少翻转几次可以全部变为0

题中要求的字典序根本不用考虑。。。

枚举第一行的翻转所有翻转情况然后逐行向下更新即可,因为第一行确定后,后面的都有唯一解

#include "stdio.h"
#include "string.h"

int n,m;
int vis[21][21],b[21][21],a[21][21],pri[21][21];

void on(int x,int y)
{
    b[x][y]^=1;
    if (x-1>=0) b[x-1][y]^=1;
    if (y-1>=0) b[x][y-1]^=1;
    b[x+1][y]^=1;
    b[x][y+1]^=1;
}

int main()
{
    int ok,ans,sum,cnt,i,j,w,key,flag;
    while (scanf("%d%d",&n,&m)!=EOF)
    {
        for (i=0;i<n;i++)
            for (j=0;j<m;j++)
            scanf("%d",&a[i][j]);

        cnt=(1<<m)-1;
        ans=0x7fffffff;
        ok=0;
        for (w=0;w<=cnt;w++)
        {
            memset(vis,0,sizeof(vis));
            memcpy(b,a,sizeof(a));
            sum=0;
            for (i=0;i<m;i++)
            {
                key=w&(1<<i);
                if (key!=0)
                {
                    sum++;
                    on(0,i);
                    vis[0][i]=1;
                }
            }
            for (i=1;i<n;i++)
            {
                if (sum>=ans) break;
                for (j=0;j<m;j++)
                if (b[i-1][j]==1)
                {
                    on(i,j);
                    vis[i][j]=1;
                    sum++;
                    if (sum>=ans) break;
                }
            }
            if (sum>=ans || i!=n) continue;
            flag=1;
            for (j=0;j<m;j++)
            if (b[n-1][j]==1) {flag=0; break;}
            if (flag==1 && sum<ans)
            {
                ok=1;
                ans=sum;
                memcpy(pri,vis,sizeof(vis));
            }
        }
        if (ok==0) printf("IMPOSSIBLE\n");
        else
        {
            for (i=0;i<n;i++)
            {
                printf("%d",pri[i][0]);
                for (j=1;j<m;j++)
                    printf(" %d",pri[i][j]);
                printf("\n");
            }
        }
    }
    return 0;
}
时间: 2024-11-08 21:49:28

POJ 3279 搜索的相关文章

POJ 3279(Fliptile)题解

以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 给定长宽的黑白棋棋盘摆满棋子,每次操作可以反转一个位置和其上下左右共五个位置的棋子的颜色,求要使用最少翻转次数将所有棋子反转为黑色所需翻转的是哪些棋子(这句话好长...). [题目分析] 盯着奇怪的题目看了半天发现和奶牛没什么卵关系..奶牛智商高了产奶高是什么鬼说法... 这题刚开始被放到搜索的分类下了..然而这和搜索有什么关系..没经验所以想了各种和搜索沾边的方法,结果没想出解法,直到看了网上的题解,压根不是搜索啊有木有.

Dearboy&#39;s Puzzle (poj 2308 搜索 dfs+bfs)

Language: Default Dearboy's Puzzle Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1202   Accepted: 208 Description Dearboy is a game lover. Recently, he loves playing the game Lian Lian Kan. This game is played on a board with N*M grids

poj 2531 搜索剪枝

Network Saboteur Time Limit: 2000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Java class name: Main [Submit] [Status] [Discuss] Description A university network is composed of N computers. System administrators gathered informat

poj 1129 搜索

Channel Allocation Time Limit: 1000 MS Memory Limit: 10000 KB 64-bit integer IO format: %I64d , %I64u Java class name: Main [Submit] [Status] [Discuss] Description When a radio station is broadcasting over a very large area, repeaters are used to ret

状态压缩+枚举 POJ 3279 Fliptile

题目传送门 1 /* 2 题意:问最少翻转几次使得棋子都变白,输出翻转的位置 3 状态压缩+枚举:和之前UVA_11464差不多,枚举第一行,可以从上一行的状态知道当前是否必须翻转 4 */ 5 #include <cstdio> 6 #include <cstring> 7 #include <algorithm> 8 using namespace std; 9 10 const int MAXN = 20; 11 const int INF = 0x3f3f3f3

poj 3279 Fliptile (简单搜索)

Fliptile Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16558   Accepted: 6056 Description Farmer John knows that an intellectually satisfied cow is a happy cow who will give more milk. He has arranged a brainy activity for cows in whic

POJ 3279 Fliptile(状压搜索)

题意 把一个n*m矩阵中的1全部变成0所需的最少步数 改变某个格子时其相邻的4个格子也一起改变 只要知道第一行改变了哪些后面的就都确定了 因为上一行对应位置是1的位置必须改变 上一行是0的一定不能改变 所以可以根据第一行的状态推出后面所有行的状态 直到最后一行结束 如果最后一行不是全0的话 这种状态就是不可行的 那么我们只用枚举第一行的所有状态就够了 m<=16 用二进制可以比较方便的枚举 对应位是1就表示改变状态 0就不改变 最后打印改变状态次数最少的可行结果就行了 http://ikando

POJ 3279 Fliptile (二进制+搜索)

[题目链接]click here~~ [题目大意]: 农夫约翰知道聪明的牛产奶多.于是为了提高牛的智商他准备了如下游戏.有一个M×N 的格子,每个格子可以翻转正反面,它们一面是黑色,另一面是白色.黑色的格子翻转后就是白色,白色的格子翻转过来则是黑色.游戏要做的就是把所有的格子都翻转成白色.不过因为牛蹄很大,所以每次翻转一个格子时,与它上下左右相邻接的格子也会被翻转.因为翻格子太麻烦了,所以牛都想通过尽可能少的次数把所有格子都翻成白色.现在给定了每个格子的颜色,请求出用最小步数完成时每个格子翻转的

【POJ 3279 Fliptile】开关问题,模拟

题目链接:http://poj.org/problem?id=3279 题意:给定一个n*m的坐标方格,每个位置为黑色或白色.现有如下翻转规则:每翻转一个位置的颜色,与其四连通的位置都会被翻转,但注意只扩散一圈,不是连锁反应. 求最少翻转几个位置能够使所有n*m个位置都变为白色.若有解,求字典序最小的翻转方案(给出每个位置的翻转次数). 数据范围:n, m 属于 [1, 15] 思路:我们把翻转方案中的翻转称为“主动翻转”,翻转过程中受邻居影响而发生的翻转称为“被动翻转”.观察例子可得出如下几个