题目链接: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 翻格子游戏:部分枚举 位运算的更多相关文章

  1. bzoj 1647: [Usaco2007 Open]Fliptile 翻格子游戏【dfs】

    这个可以用异或高斯消元,但是我不会呀我用的暴搜 2的m次方枚举第一行的翻转情况,然后后面的就定了,因为对于一个j位置,如果i-1的j位置需要翻,那么一定要翻i的j,因为这是i-1的j最后翻的机会 按字 ...

  2. 1647: [Usaco2007 Open]Fliptile 翻格子游戏

    1647: [Usaco2007 Open]Fliptile 翻格子游戏 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 423  Solved: 173[ ...

  3. 【BZOJ】1647: [Usaco2007 Open]Fliptile 翻格子游戏(暴力)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1647 自己太弱...看题解.. 竟然是枚举第一行的放法,,,因为一定要全部变0,所以将前一行1的在这 ...

  4. [Usaco2007 Open]Fliptile 翻格子游戏

    [Usaco2007 Open]Fliptile 翻格子游戏 题目 Farmer John knows that an intellectually satisfied cow is a happy ...

  5. [Usaco2007 Open]Fliptile 翻格子游戏题解

    问题 B: [Usaco2007 Open]Fliptile 翻格子游戏 时间限制: 5 Sec  内存限制: 128 MB 题目描述 Farmer John knows that an intell ...

  6. 【BZOJ 1647】[Usaco2007 Open]Fliptile 翻格子游戏 模拟、搜索

    第一步我们发现对于每一个格子,我们只有翻和不翻两种状态,我们发现一旦确定了第一行操作,那么第二行的操作也就随之确定了,因为第一行操作之后我们要想得到答案就得把第一行全部为0,那么第二行的每一个格子的操 ...

  7. [Usaco2007 Open]Fliptile 翻格子游戏 状态压缩

    考试想到了状压,苦于T1废掉太长时间,于是默默输出impossible.. 我们知道,一个格子的翻转受其翻转次数和它相邻翻转次数的影响. 由每一个位置操作两次相当于把它翻过来又翻回去,所以答案中每一个 ...

  8. [Usaco2007 Open]Fliptile 翻格子游戏 状压dp

    n,m<=15,直接搞肯定不行,考虑一行一行来, 每一行的状态只与三行有关,所以从第一行开始枚举,每一次让下面一行填上他上面那行的坑 最后一行必须要同时满足他自己和他上面那行,否则舍去 #inc ...

  9. [BZOJ 1647][USACO 2007 Open] Fliptile 翻格子游戏

    1647: [Usaco2007 Open]Fliptile 翻格子游戏 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 702  Solved: 281[ ...

随机推荐

  1. HDU 3466 01背包变形

    给出物品数量N和总钱数M 对于N个物品.每一个物品有其花费p[i], 特殊值q[i],价值v[i] q[i] 表示当手中剩余的钱数大于q[i]时,才干够买这个物品 首先对N个物品进行 q-p的排序,表 ...

  2. vue组件class绑定

    当在一个自定义组件上使用 class 属性时,这些类将被添加到该组件的根元素上面.这个元素上已经存在的类不会被覆盖. 例如,如果你声明了这个组件: Vue.component('my-componen ...

  3. LeetCode Recover Binary Search Tree——二查搜索树中两个节点错误

    Two elements of a binary search tree (BST) are swapped by mistake.Recover the tree without changing ...

  4. vs调试,监控变量

  5. VueJS样式绑定v-bind:class

    class 与 style 是 HTML 元素的属性,用于设置元素的样式,我们可以用 v-bind 来设置样式属性. Vue.js v-bind 在处理 class 和 style 时, 专门增强了它 ...

  6. HDOJ2084数塔问题

    数塔问题 题目要求从顶层走究竟层.若每一步仅仅能走到相邻的结点,求经过的结点的数字之和最大值. 非常经典的DP,能够这样考虑,要求从塔顶到塔底最大路径之和.计算时能够考虑自底向上,走最后一步所选的数一 ...

  7. 怎样给filter加入自己定义接口

    .在Cfilter类的定义中实现Interface接口的函数的定义: //-----------------------Interface methods----------------------- ...

  8. POJ 2456 Aggressive cows (二分 基础)

    Aggressive cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7924   Accepted: 3959 D ...

  9. 在eclipse中添加android ADT

    对于程序开发的学者来说,eclipse并不陌生,它为我们提供了一个非常广阔的平台来开发程序.同样我们也可以用它来开发android程序. 但是在eclipse中并不能直接开发android程序,需要我 ...

  10. HDFS源码分析之编辑日志编辑相关双缓冲区EditsDoubleBuffer

    EditsDoubleBuffer是为edits准备的双缓冲区.新的编辑被写入第一个缓冲区,同时第二个缓冲区可以被flush.为edits准备的双缓冲区.新的编辑被写入第一个缓冲区,同时第二个缓冲区可 ...