昨天晚上12点刷到的这个题,一开始一位是BFS,但是一直没有思路。后来推了一下发现只需要依次枚举第一行的所有翻转状态然后再对每个情况的其它田地翻转进行暴力dfs就可以,但是由于二进制压缩学的不是很透,一直有小问题,下面我还会讲子集生成的相关方法,有兴趣的同学可以继续关注。

  本题大意:一块地,有黑(1)白(0)之分,牛每次踩踏使得当前块以及四连块都变色,问当牛如何踩时使得地都变白并且求出最小踩踏次数和踩踏路径的最小字典序时的踩踏地图。

  本题思路:由于同一块地被翻两次都会回到原来的状态,所以只需要对应每块地看他上方的地是否为黑色,为黑色则翻否则看其他情况,由于第一排的黑色只有第二排能翻,所以需要先对第一排进行枚举,然后再对其剩余的状态进行搜索即可。那么如何判断某块地是否为黑色呢,这里我们采用二进制压缩,大意就是从1 -(1 << n) 的所有数字即逆序枚举了所有状态,然后访问每个状态,如果此地上方的为白色地则跳过,黑色地则进行翻转。具体如下图所示。

  首先我们假设有m == 4列,则它所对应的数字如下图所示。

每个数对应的二进制码位如果为1则翻转,否则不翻转。

  参考代码:

 #include <cstdio>
#include <cstring>
using namespace std; const int maxn = + , INF = 0x3f3f3f;
int n, m, minx = INF;
int maze[maxn][maxn], temp[maxn][maxn], vis[maxn][maxn], ans[maxn][maxn];
int dx[] = {, , -, }, dy[] = {, , , -}; void reverse(int u, int v) {
vis[u][v] = ;
temp[u][v] = !temp[u][v];
for(int p = ; p < ; p ++) {
int ni = u + dx[p], nj = v + dy[p];
if(ni >= && nj >= && ni < n && nj < m)
temp[ni][nj] = !temp[ni][nj];
}
} bool Judge() {
for(int i = ; i < n; i ++)
for(int j = ; j < m; j ++)
if(temp[i][j] == ) return false;
return true;
} void solve(int x) {
memcpy(temp, maze, sizeof(maze));
memset(vis, , sizeof(vis));
int cnt = ;
for(int i = ; i < m; i ++) {
if((x >> i) & ) {
cnt ++;
reverse(, i);
}
}
for(int i = ; i < n; i ++) {
for(int j = ; j < m; j ++) {
if(temp[i - ][j] == ) {
reverse(i, j);
cnt ++;
}
}
}
if(Judge() && cnt < minx) {
minx = cnt;
memcpy(ans, vis, sizeof(vis));
}
} int main () {
scanf("%d %d", &n, &m);
for(int i = ; i < n; i ++)
for(int j = ; j < m; j++)
scanf("%d", &maze[i][j]);
for(int i = ; i < ( << m); i ++)
solve(i);
if(minx == INF)
printf("IMPOSSIBLE\n");
else {
for(int i = ; i < n; i ++) {
for(int j = ; j < m - ; j ++) {
printf("%d ", ans[i][j]);
}
printf("%d\n", ans[i][m - ]);
}
}
return ;
}

View Cod

POJ-3279.Fliptile(二进制状态压缩 + dfs) 子集生成的更多相关文章

  1. POJ 3279 Fliptile[二进制状压DP]

    题目链接[http://poj.org/problem?id=3279] 题意:给出一个大小为M*N(1 ≤ M ≤ 15; 1 ≤ N ≤ 15) 的图,图中每个格子代表一个灯泡,mp[i][j] ...

  2. poj 3279 Fliptile(二进制)

    http://poj.org/problem?id=3279 在n*N的矩阵上,0代表白色,1代表黑色,每次选取一个点可以其颜色换过来,即白色变成黑色,黑色变成白色,而且其上下左右的点颜色也要交换,求 ...

  3. POJ 3279 Fliptile (二进制枚举)

    <题目链接> <转载于 >>> > 题目大意: 给定一个M*N矩阵,有些是黑色(1表示)否则白色(0表示),每翻转一个(i,j),会使得它和它周围4个格变为另 ...

  4. poj 3279 Fliptile(二进制搜索)

    Farmer John knows that an intellectually satisfied cow is a happy cow who will give more milk. He ha ...

  5. 状态压缩+枚举 POJ 3279 Fliptile

    题目传送门 /* 题意:问最少翻转几次使得棋子都变白,输出翻转的位置 状态压缩+枚举:和之前UVA_11464差不多,枚举第一行,可以从上一行的状态知道当前是否必须翻转 */ #include < ...

  6. UVA 1508 - Equipment 状态压缩 枚举子集 dfs

    UVA 1508 - Equipment 状态压缩 枚举子集 dfs ACM 题目地址:option=com_onlinejudge&Itemid=8&category=457& ...

  7. POJ.3279 Fliptile (搜索+二进制枚举+开关问题)

    POJ.3279 Fliptile (搜索+二进制枚举+开关问题) 题意分析 题意大概就是给出一个map,由01组成,每次可以选取按其中某一个位置,按此位置之后,此位置及其直接相连(上下左右)的位置( ...

  8. POJ 2777.Count Color-线段树(区间染色+区间查询颜色数量二进制状态压缩)-若干年之前的一道题目。。。

    Count Color Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 53312   Accepted: 16050 Des ...

  9. POJ 3279 Fliptile(翻格子)

    POJ 3279 Fliptile(翻格子) Time Limit: 2000MS    Memory Limit: 65536K Description - 题目描述 Farmer John kno ...

随机推荐

  1. tensorflow实战系列(三)一个完整的例子

    #!/usr/bin/env python2# -*- coding: utf-8 -*-"""Created on Wed Jan 18 08:42:55 2017 @ ...

  2. EasyARM-iMX283A的Linux 开发环境构建

    Vim的安装 sudo apt-get install vim 等待安装完成后我们来配置简单配置vim的配置文件 vim /etc/vim/vimrc (备注:自己一个人使用的^-^) 在原来的基础上 ...

  3. 使用STM32CubeMX生成USB_HOST_HID工程

    使用开发板为STM32F105开发板. 原本想将具体步骤给写出来.时间有限.直接将STM32F105_USBH_HID.IOC上传files.cnblogs.com/files/libra13179/ ...

  4. 通过HTTP请求响应过程了解HTTP协议

    通过HTTP请求响应过程了解HTTP协议 http://www.cnblogs.com/YeChing/p/6337378.html

  5. 尚硅谷springboot学习15-日志框架1-入门

    引子 小张:开发一个大型系统 1.System.out.println(""):将关键数据打印在控制台:去掉?写在一个文件? ​ 2.框架来记录系统的一些运行时信息:日志框架 : ...

  6. 四则运算之Right-BICEP单元测试

    一. 这篇博客要对上次实现的四则运算进行单元测试,一是检查上次的程序的实现情况,二是巩固单元测试的相关知识.本次进行单元测试用的是Riget-BICEP方法. Riget-BICEP方法: 1.Rig ...

  7. [PHP]Nginx与PHP的文件上传大小限制

    ---------------------------------------------------------------------------------------------------- ...

  8. JS实现简单的运行代码 & 侧边广告

    /* JS实现简单的运行代码功能 */<!doctype html> <html> <head> <meta charset="utf-8" ...

  9. 基于Delphi的接口编程入门

    为什么使用接口? 举个例子好了:有这样一个卖票服务,电影院可以卖票,歌剧院可以卖票,客运站也可以卖票,那么我们是否需要把电影院..歌剧院和客运站都设计成一个类架构以提供卖票服务?要知道,连经理人都可以 ...

  10. [译]CQRS介绍

    以下内容均为看完原文后自己的理解.并非一字一句翻译,会尽量保持原文意思. 什么是 CQRS: CQRS 意思就是命令查询职责分离(Command Query Responsibility Segreg ...