HDU 1882 Strange Billboard(位运算)
题意 : 给你一个矩阵,有黑有白,翻转一个块可以让上下左右都翻转过来,问最少翻转多少次能让矩阵变为全白。
思路 : 我们从第一行开始枚举要翻转的状态,最多可以枚举到2的16次方,因为你只要第一行的确定了,第二行要翻转的也就确定了,所以第一行的状态决定了最后的状态。看了网上大神,真是让位运算废了啊,,,,,太复杂了。。。。。。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <map> using namespace std; const int INF = ;
int r,c,n;
int data[] ; void Init()
{
char mapp[][] ;
memset(data,,sizeof(data)) ;
if(r >= c)
{
for(int i = ; i < r ; i++)//每一行都用一个二进制数来保存
{
data[i] = ;
scanf("%s",mapp[i]) ;
for(int j = ; j < c ; j++)
{
if(mapp[i][j] == 'X')
data[i] |= << j ;//这一行中将是X的地方全部存为1
}
}
}
else//优化,当列比较少的时候就翻转过来用列。
{
for(int i = ; i < r ; i++)
{
data[i] = ;
scanf("%s",mapp[i]) ;
for(int j = ; j < c ; j++)
if(mapp[i][j] == 'X')
data[j] |= << i ;
}
//把r和c的两值互换
r = r^c ;
c = r^c ;
r = r^c ;
}
}
void solve()
{
int minn = INF ;
int a[],tmp[] ;
for(int i = ; i < ( << c) ; i++)//枚举状态,共有2的c次方个
{
for(int j = ; j < r ; j++)
a[j] = data[j] ;
for(int j = ; j < r ; j++)
{
tmp[j] = j == ? i : a[j-] ;
a[j] ^= tmp[j] ;//本行要翻转
a[j] ^= tmp[j] >> ;//右边也要翻转
a[j] ^= tmp[j] << & (( << c)-) ;//防止最左边的那位超出范围
a[j+] ^= tmp[j] ;//下一行也要翻转
}
if(!a[r-])//因为第一行确定之后第二行也就确定了,以此类推,只要判断最后一行是不是全白就行了
{
int cnt = ;
for(int j = ; j < r ; j++)
{
for(int k = tmp[j] ; k > ; k >>= )
if( & k) cnt ++ ;
}
if(cnt < minn) minn = cnt ;
}
}
if(minn == INF)
printf("Damaged billboard.\n") ;
else printf("You have to tap %d tiles.\n",minn) ;
}
int main()
{
while(~scanf("%d %d",&r,&c))
{
if(r == && c == )
break ;
Init() ;
solve() ;
}
return ;
}
如果那四行看不懂,没关系,因为我也看不太懂,看这里应该比较好理解一点,就是翻本行,翻左边那一列,右边那一列,下一行
HDU 1882 Strange Billboard(位运算)的更多相关文章
- hdu 1882 Strange Billboard(位运算+枚举)
http://acm.hdu.edu.cn/showproblem.php?pid=1882 感觉非常不错的一道题. 给一个n*m(1<=n,m<=16)的矩阵,每一个格子都有黑白两面,当 ...
- HDU 1882 Strange Billboard(状态压缩+转置优化)
状态压缩,我们枚举第一行的所有状态,然后根据第一行去转变下面的行,枚举或者深搜直到最后最后一行,可以判断是不是所有的1都可以全部转换为0,记录所有的解,输出最小的一个就可以. 这里有一个很重要的优化, ...
- hdu 5023 线段树+位运算
主要考线段树的区间修改和区间查询,这里有一个问题就是这么把一个区间的多种颜色上传给父亲甚至祖先节点,在这里题目告诉我们最多30颜色,那么我们可以把这30中颜色用二进制储存和传给祖先节点,二进制的每一位 ...
- HDU 5491 The Next(位运算)
题意:已知D(0<=D<2^31).s1.s2,其中L为D转化为二进制数时1的个数,题目保证s1<=L<=s2,求一个数,满足以下条件: 1.比D大 2.转化为二进制时1的个数 ...
- [HDU] 3711 Binary Number [位运算]
Binary Number Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tot ...
- HDU - 6186 前缀和位运算
异或操作蒙蔽了我的双眼 以至于没有第一时间想到前缀和与后缀和 水题做的不够多 #include<bits/stdc++.h> #define rep(i,j,k) for(register ...
- HDU 3006 The Number of set(位运算 状态压缩)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3006 题目大意:给定n个集合,每个集合都是由大于等于1小于等于m的数字组成,m最大为14.由给出的集合 ...
- hdu 4739【位运算】.cpp
题意: 给出n个地雷所在位置,正好能够组成正方形的地雷就可以拿走..为了简化题目,只考虑平行于横轴的正方形.. 问最多可以拿走多少个正方形.. 思路: 先找出可以组成正方形的地雷组合cnt个.. 然后 ...
- HDU 1074 Doing Homework (动态规划,位运算)
HDU 1074 Doing Homework (动态规划,位运算) Description Ignatius has just come back school from the 30th ACM/ ...
随机推荐
- Vim 保存和退出命令
命令 简单说明 :w 保存编辑后的文件内容,但不退出vim编辑器.这个命令的作用是把内存缓冲区中的数据写到启动vim时指定的文件中. :w! 强制写文件,即强制覆盖原有文件.如果原有文件的访问权限不允 ...
- SNRO:Number Range
业务对象是在一定的编号范围内分配编号的,编号既可以是内部分配也可以是外部分配.对于外部分配,用户输入编号,系统检查这个编号是否被占用.对于内部分配,系统会自动的把编号分配给业务对象.所以内部分配和外部 ...
- AndroidStudio支持新的NDK的操作使用
在2015的Google I / O大会,5月底,谷歌宣布了一项新的支持由Android NDK Studio 1.3,Jetbrains CLion集成功能,Android gradle插件.这种支 ...
- javascript 数字字符串转为数字
var a="111"; comsole.log(a); //打印出来是个字符串类型 comsole.log(+a); //打印出来是个数字类型 comsole.log ...
- seajs构建方法
标准构建 如果项目遵循推荐的标准目录结构: foo-module/ |-- dist //存放构建好的文件 |-- src ...
- visual studio中创建单元测试
1 打开 工具--自定义 2 选择 上下文菜单--编辑器上下文菜单|代码窗口 3 在这里我们可以看到“创建单元测试”这个菜单了,将它移到运行测试菜单下面 4 关闭VS并重启 重启后再对着类名,点击右 ...
- C# 编写Window服务基础(一)
一.Windows服务介绍: Windows服务以前被称作NT服务,是一些运行在Windows NT.Windows 2000和Windows XP等操作系统下用户环境以外的程序.在以前,编写Wind ...
- php取得当前访问url文件名的几种方法
php下获取当前访问的文件名的几种方法.推荐函数:一是PHP获取当前页面的网址: dedecms用的也是这个哦. <?php //获得当前的脚本网址 function GetCurUrl() { ...
- sql中的系统表sysobjects以及如何查看sql语句的执行时间
使用sysobjects可以快速查看数据库中表.视图.存储过程.触发器.约束等的信息. 大牛文章:http://www.cnblogs.com/atree/p/SQL-Server-sysobject ...
- (转)MapReduce中的两表join几种方案简介
转自:http://blog.csdn.net/leoleocmm/article/details/8602081 1. 概述 在传统数据库(如:MYSQL)中,JOIN操作是非常常见且非常耗时的.而 ...