考试想到了状压,苦于T1废掉太长时间,于是默默输出impossible。。
我们知道,一个格子的翻转受其翻转次数和它相邻翻转次数的影响。
由每一个位置操作两次相当于把它翻过来又翻回去,所以答案中每一个点操作次数为0或1。
然后我们枚举第一行的状态,1代表翻转,0代表不翻转。
如果与它相连的点的操作次数和它本身状态之和为偶数,它就会被翻成白色。
由于我们从上向下推,所以对于上一行的点来说,只有它下面那一个点不确定,我们就让下面这一个点进行能够让上一行点满足全为白色的操作。
这样推到最后一行,前面m-1行都满足,我们只需要看最后一行是否满足就可以了。
最后一行满足,就说明这种方案合法,再去更新之前存下的合法方案就可以了。

例如此位置本身与上左右状态之和为偶数,而此位置在初始时是1,所以我们需要把它翻成0,需要奇数个操作,所以我们把它下面的状态设置为1即可。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define pos(i,a,b) for(int i=(a);i<=(b);i++)
#define N 20
int n,m;
int a[N][N],temp[N][N],ans[N][N];
int work(int i){
	pos(j,1,n){
		if(j==1){
			pos(k,1,m)
				if((1<<(m-k))&i){
					temp[j][k]=1;
				}
		}
		pos(k,1,m){
			if(j!=n){
					if((temp[j][k-1]+temp[j][k+1]+temp[j-1][k]+temp[j][k])%2==0){
					if(a[j][k]){
						temp[j+1][k]=1;
					}
					else{
						temp[j+1][k]=0;
					}
				}
				else{
					if(a[j][k]==0){
						temp[j+1][k]=1;
					}
					else{
						temp[j+1][k]=0;
					}
				}
			}
			if(j==n){
				if((temp[j][k-1]+temp[j][k+1]+temp[j-1][k]+temp[j][k])%2==0){
					if(a[j][k]){
						return 0;
					}
				}
				else{
					if(!a[j][k])
					  return 0;
				}
			}
		}
	}
	return 1;
}
int flag;
int count(){
	int sum1=0,sum2=0;;
	pos(i,1,n){
		pos(j,1,m){
			if(temp[i][j])
			  sum1++;
			if(ans[i][j])
				sum2++;
		}
	}
	if(sum1<sum2)
	  return 1;
	return 0;
}
void update(){
	if(flag){
		if(count()){
			pos(i,1,n)
				pos(j,1,m)
					ans[i][j]=temp[i][j];
		}
		else{
			pos(i,1,n){
				pos(j,1,m){
					if(temp[i][j]<ans[i][j]){
						pos(k,1,n){
							pos(l,1,m){
								ans[k][l]=temp[k][l];
							}
						}
					}
					else{
						return;
					}
				}
			}
		}
	}
	else{
		pos(i,1,n)
			pos(j,1,m)
				ans[i][j]=temp[i][j];
		flag=1;
	}
}
int main(){
	//freopen("fliptile.in","r",stdin);
    //freopen("fliptile.out","w",stdout);
	scanf("%d%d",&n,&m);
	pos(i,1,n){
		pos(j,1,m){
			scanf("%d",&a[i][j]);
		}
	}
	pos(i,0,(1<<m)-1){
		memset(temp,0,sizeof(temp));
		if(work(i)){
			update();
		}
		else{
			continue;
		}
	}
	if(flag){
		pos(i,1,n){
			pos(j,1,m){
				cout<<ans[i][j]<<" ";
			}
			cout<<endl;
		}
	}
	else{
		cout<<"IMPOSSIBLE";
	}
	return 0;
}

  

[Usaco2007 Open]Fliptile 翻格子游戏 状态压缩的更多相关文章

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

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

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

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

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

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

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

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

  5. BZOJ 1647 [Usaco2007 Open]Fliptile 翻格子游戏:部分枚举 位运算

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1647 题意: 在一个n*m(1 <= n,m <= 15)的棋盘上,每一个格子 ...

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

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

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

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

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

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

  9. Fliptile 翻格子游戏

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

随机推荐

  1. 简单的视频采集demo

    打算做个简单的聊天软件,其中一个我没做过的,就是视频采集. 在网上查了许久资料,终于搞清楚了dshow采集视频的流程 参考资料如下: https://msdn.microsoft.com/en-us/ ...

  2. CSS学习笔记10 相对定位,绝对定位与固定定位

    文档流中的元素的位置由元素在 (X)HTML 中的位置决定,这就是最原始的普通流,前面讲到的浮动CSS学习笔记08 浮动可以改变元素在文档流中的位置,除了这个我们还可以通过使用CSS的position ...

  3. sizzle选择器的使用

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  4. JUnit【1】断言用法之assertEquals/True/False/ArrayEquals

    前段时间去亚信面试,被问到写一个冒泡排序,心想这多新鲜,刷刷几下写好.面试官突然问,你怎么对这个程序进行单元测试?    单元测试?!    懵圈...      单元测试      代码是为了什么, ...

  5. 前端需要注意的seo

    1 合理的title ,description ,keyswords 搜索引擎对这三项的权重逐渐减小,title 强调重点即可 ,重要的关键字不要超过两次,而且要靠前. 2 不同的tilte要有所不同 ...

  6. (转载)DBCP、C3P0、Proxool 、 BoneCP开源连接池的比较

    原文链接: http://blog.csdn.net/miclung/article/details/7231553    简介   使用评价  项目主页  DBCP DBCP是一个依赖Jakarta ...

  7. iOS动画学习-CALayer

    iOS中有很多方法可以实现动画,我们可以用CAKeyframeAnimation, CABasicAnimation,CASpringAnimation(iOS9.0中添加的,实现弹簧的效果),也可以 ...

  8. voa 2015 / 4 / 15

    illustrated - v. to explain or decorate a story, book, etc., with pictures pediatrician – n. a docto ...

  9. 上传图片并生成相关缩略图-PHP

    if(!empty($_FILES["fileField"]["name"])){//检测表单传递文件数据 $fileinfo = $_FILES[" ...

  10. Java用Cookie简单限制点赞次数

    楼主最近在搞一个当下比较流行的点赞功能,这个功能也是让程序员又爱又恨啊 说起爱,点赞是个社会化的动作,全民都在为美好的事情,行为,动作,点赞. 说起恨,你很难在用户没有登录的情况下限制恶意点赞的机器人 ...