BZOJ 1647 [Usaco2007 Open]Fliptile 翻格子游戏:部分枚举 位运算
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1647
题意:
在一个n*m(1 <= n,m <= 15)的棋盘上,每一个格子里都有一个可以翻转的棋子。
棋子的一面是黑色,一面是白色。
若翻转一个棋子,则它周围的四个棋子也会被翻转。
问你最少需要多少次翻转,使所有的棋子都变成白面向上。
如果可以做到,输出字典序最小的结果(将结果当成字符串处理)。如果不能做到,输出“IMPOSSIBLE”。
题解:
首先有一个结论:
如果第i-1行第j列的棋子为黑,那么第i行j列的棋子一定会被翻转,因为只有这样上一行的黑棋子才能变成白棋子。
所以,如果上一行的棋子状态已经确定,那么当前行的翻转方案是唯一确定的。
因此,如果第1行的棋子状态确定,接下来2到n行的方案也都唯一确定了。
所以只用枚举第1行的棋子状态,复杂度O(2^15)。
注:如果用状态压缩state枚举表示第一行的状态的话,state的第0位代表棋盘的第m-1列。
因为要按字典序从小到大枚举。
AC Code:
#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_N 20
#define INF 10000000 using namespace std; const int dx[]={-,,,};
const int dy[]={,,-,}; int n,m;
int a[MAX_N][MAX_N];
int t[MAX_N][MAX_N];
int cnt[MAX_N][MAX_N];
int ans[MAX_N][MAX_N];
bool failed=false; void read()
{
cin>>n>>m;
for(int i=;i<n;i++)
{
for(int j=;j<m;j++)
{
cin>>a[i][j];
}
}
} inline bool is_legal(int x,int y)
{
return x>= && x<n && y>= && y<m;
} void solve()
{
int minn=INF;
for(int state=;state<(<<m);state++)
{
memset(cnt,,sizeof(cnt));
memcpy(t,a,sizeof(int)*MAX_N*MAX_N);
int tot=;
for(int j=;j<m;j++)
{
int pos=m-j-;
if((state>>pos)&)
{
t[][j]^=;
cnt[][j]=;
tot++;
for(int k=;k<;k++)
{
int x=dx[k];
int y=j+dy[k];
if(is_legal(x,y)) t[x][y]^=;
}
}
}
for(int i=;i<n;i++)
{
for(int j=;j<m;j++)
{
if(t[i-][j])
{
t[i][j]^=;
cnt[i][j]=;
tot++;
for(int k=;k<;k++)
{
int x=i+dx[k];
int y=j+dy[k];
if(is_legal(x,y)) t[x][y]^=;
}
}
}
}
bool is_white=true;
for(int j=;j<m;j++)
{
if(t[n-][j])
{
is_white=false;
break;
}
}
if(is_white && tot<minn)
{
memcpy(ans,cnt,sizeof(int)*MAX_N*MAX_N);
minn=tot;
}
}
if(minn==INF) failed=true;
} void print()
{
if(failed)
{
cout<<"IMPOSSIBLE"<<endl;
return;
}
for(int i=;i<n;i++)
{
for(int j=;j<m;j++)
{
cout<<ans[i][j];
if(j!=m-) cout<<" ";
}
cout<<endl;
}
} int main()
{
read();
solve();
print();
}
BZOJ 1647 [Usaco2007 Open]Fliptile 翻格子游戏:部分枚举 位运算的更多相关文章
- bzoj 1647: [Usaco2007 Open]Fliptile 翻格子游戏【dfs】
这个可以用异或高斯消元,但是我不会呀我用的暴搜 2的m次方枚举第一行的翻转情况,然后后面的就定了,因为对于一个j位置,如果i-1的j位置需要翻,那么一定要翻i的j,因为这是i-1的j最后翻的机会 按字 ...
- 1647: [Usaco2007 Open]Fliptile 翻格子游戏
1647: [Usaco2007 Open]Fliptile 翻格子游戏 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 423 Solved: 173[ ...
- 【BZOJ】1647: [Usaco2007 Open]Fliptile 翻格子游戏(暴力)
http://www.lydsy.com/JudgeOnline/problem.php?id=1647 自己太弱...看题解.. 竟然是枚举第一行的放法,,,因为一定要全部变0,所以将前一行1的在这 ...
- [Usaco2007 Open]Fliptile 翻格子游戏
[Usaco2007 Open]Fliptile 翻格子游戏 题目 Farmer John knows that an intellectually satisfied cow is a happy ...
- [Usaco2007 Open]Fliptile 翻格子游戏题解
问题 B: [Usaco2007 Open]Fliptile 翻格子游戏 时间限制: 5 Sec 内存限制: 128 MB 题目描述 Farmer John knows that an intell ...
- 【BZOJ 1647】[Usaco2007 Open]Fliptile 翻格子游戏 模拟、搜索
第一步我们发现对于每一个格子,我们只有翻和不翻两种状态,我们发现一旦确定了第一行操作,那么第二行的操作也就随之确定了,因为第一行操作之后我们要想得到答案就得把第一行全部为0,那么第二行的每一个格子的操 ...
- [Usaco2007 Open]Fliptile 翻格子游戏 状态压缩
考试想到了状压,苦于T1废掉太长时间,于是默默输出impossible.. 我们知道,一个格子的翻转受其翻转次数和它相邻翻转次数的影响. 由每一个位置操作两次相当于把它翻过来又翻回去,所以答案中每一个 ...
- [Usaco2007 Open]Fliptile 翻格子游戏 状压dp
n,m<=15,直接搞肯定不行,考虑一行一行来, 每一行的状态只与三行有关,所以从第一行开始枚举,每一次让下面一行填上他上面那行的坑 最后一行必须要同时满足他自己和他上面那行,否则舍去 #inc ...
- [BZOJ 1647][USACO 2007 Open] Fliptile 翻格子游戏
1647: [Usaco2007 Open]Fliptile 翻格子游戏 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 702 Solved: 281[ ...
随机推荐
- mysql使用mysqldump 与 mysqlimport进行数据库迁移
1.导入数据库 1)source source /home/platvt/product/pc2_create_tables.sql 2)mysqlimport 使用mysqlimport导入数据: ...
- jquery插件范例代码
// 创建一个闭包 (function($) { // 插件的定义 $.fn.hilight = function(options) { debug(this); // build main opti ...
- 【电子签章】HTML格式合同转化成PDF文件
代码地址如下:http://www.demodashi.com/demo/12476.html 一.主要思路 通过itextpdf 生成想要的pdf 文件 通过itextpdf 中 XMLWorker ...
- DevOps 初学者的入门指南
原文地址:http://blog.csdn.net/FIRim/article/details/52681704 当我们谈到 DevOps 时,可能讨论的是:流程和管理,运维和自动化,架构和服务,以及 ...
- 单点登录系统cas资料汇总
http://jasig.github.io/cas/4.0.x/index.html 主页 https://jasigcas.herokuapp.com ...
- CSS解决无空格太长的字母,数字不会自己主动换行的问题
事实上非常easy,代码例如以下所看到的,注意 Style: <div class="detail_title" style="word-break: break- ...
- Java 线程第三版 第五章 极简同步技巧 读书笔记
一.能避免同步吗? 取得锁会由于下面原因导致成本非常高: 取得由竞争的锁须要在虚拟机的层面上执行很多其它的程序代码. 要取得有竞争锁的线程总是必须等到锁被释放后. 1. 寄存器的效应 ...
- 汉字unicode码表范围和常用汉字unicode码
utf-8吗表中所有汉字的区间的正则表达式[\u4e00-\u9fa5] 汉字常用字unicode吗表String base ="\u7684\u4e00\u4e86\u662f\u6211 ...
- OpenCV2马拉松第15圈——边缘检測(Laplace算子,LOG算子)
收入囊中 拉普拉斯算子 LOG算子(高斯拉普拉斯算子) OpenCV Laplacian函数 构建自己的拉普拉斯算子 利用拉普拉斯算子进行图像的锐化 葵花宝典 在OpenCV2马拉松第14圈--边缘检 ...
- C#使用for循环移除HTML标记
public static string StripTagsCharArray(string source) { char[] array = new char[source.Length]; int ...