poj1753-Flip Game(高斯消元枚举xor线性方程自由变元的值,找为1解的最少数量)

Flip Game

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 31227   Accepted: 13583

Description

Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 squares. One side of each piece is white and the other one is black and each piece is lying either it‘s black or white side up. Each
round you flip 3 to 5 pieces, thus changing the color of their upper side from black to white and vice versa. The pieces to be flipped are chosen every round according to the following rules:

  1. Choose any one of the 16 pieces.
  2. Flip the chosen piece and also all adjacent pieces to the left, to the right, to the top, and to the bottom of the chosen piece (if there are any).

Consider the following position as an example:

bwbw

wwww

bbwb

bwwb

Here "b" denotes pieces lying their black side up and "w" denotes pieces lying their white side up. If we choose to flip the 1st piece from the 3rd row (this choice is shown at the picture), then the field will become:

bwbw

bwww

wwwb

wwwb

The goal of the game is to flip either all pieces white side up or all pieces black side up. You are to write a program that will search for the minimum number of rounds needed to achieve this goal.

Input

The input consists of 4 lines with 4 characters "w" or "b" each that denote game field position.

Output

Write to the output file a single integer number - the minimum number of rounds needed to achieve the goal of the game from the given position. If the goal is initially achieved, then write 0. If it‘s impossible to achieve the
goal, then write the word "Impossible" (without quotes).

Sample Input

bwwb
bbwb
bwwb
bwww

Sample Output

4

Source

Northeastern Europe 2000

#include<iostream>
#include<map>
#include<string>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=100;
const int maxm=100;
const int inf=0xfffffff;
int a[maxn][maxm],x[maxm];
int gauss(int n)
{
	int row,line,i,j,m,free[maxm],cnt=0,t,mn,sum,k;
	for(row=line=0;line<n;row++,line++)
	{
		i=row;
		for(j=row+1;j<n;j++)
			if(a[j][line]>a[i][line])
				i=j;
		if(i!=row)
			for(j=row;j<=n;j++)
				swap(a[i][j],a[row][j]);
		if(a[row][line]==0)
		{
			free[cnt++]=line;
			row--;
			continue;
		}
		for(i=row+1;i<n;i++)
			if(a[i][line]==1)
				for(j=line;j<=n;j++)
					a[i][j]^=a[row][j];
	}
	for(i=row;i<n;i++)
		if(a[i][n]==1)
			return -1;
	mn=inf;
	m=1<<cnt;
	memset(x,0,sizeof(x));
	for(i=0;i<m;i++)
	{
		t=i;
		sum=0;
		for(j=0;j<cnt;j++)
		{
			x[free[j]]=t&1;
			if(x[free[j]]==1)
				sum++;
			t>>=1;
		}
		for(j=row-1;j>-1;j--)
		{
			x[j]=a[j][n];
			for(k=j+1;k<n;k++)
				x[j]^=a[j][k]&x[k];
			if(x[j]==1)
				sum++;
		}
		mn=min(sum,mn);
	}
	return mn;
}
void init(int n)
{
	int i,j,t;
	memset(a,0,sizeof(a));
	for(i=0;i<n;i++)
		for(j=0;j<n;j++)
		{
			t=i*n+j;
			a[t][t]=1;
			if(i!=0)
				a[(i-1)*n+j][t]=1;
			if(i!=n-1)
				a[(i+1)*n+j][t]=1;
			if(j!=0)
				a[t-1][t]=1;
			if(j!=n-1)
				a[t+1][t]=1;
		}
}
int main()
{
	int i,j,n=4,ans,m=16,t;
	char s[maxn][maxm];
	while(scanf("%s",s[0])!=EOF)
	{
		for(i=1;i<n;i++)
			scanf("%s",s[i]);
		init(n);
		for(i=0;i<n;i++)
			for(j=0;j<n;j++)
				if(s[i][j]=='b')
					a[i*n+j][m]=1;
		t=gauss(m);
		t=t==-1?inf:t;
		init(n);
		for(i=0;i<n;i++)
			for(j=0;j<n;j++)
				if(s[i][j]=='w')
					a[i*n+j][m]=1;
		ans=gauss(m);
		ans=ans==-1?inf:ans;
		ans=min(ans,t);
		if(ans==inf)
			printf("Impossible\n");
		else
			cout<<ans<<endl;
	}
}
时间: 2024-10-17 17:32:22

poj1753-Flip Game(高斯消元枚举xor线性方程自由变元的值,找为1解的最少数量)的相关文章

POJ 1753 Flip Game (高斯消元 枚举自由变元求最小步数)

题目链接 题意:4*4的黑白棋,求把棋全变白或者全变黑的最小步数. 分析:以前用状态压缩做过. 和上题差不多,唯一的不同是这个终态是黑棋或者白棋, 但是只需要把给的初态做不同的两次处理就行了. 感觉现在还只是会套模板,不能独立的思考,好伤心.... 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath&g

Light OJ 1272 Maximum Subset Sum 高斯消元 最大XOR值

题目来源:Light OJ 1272 Maximum Subset Sum 题意:选出一些数 他们的抑或之后的值最大 思路:每个数为一个方程 高斯消元 从最高位求出上三角 消元前k个a[i]异或和都能有消元后的异或和组成 消元前 k 个 a[i] a[i]异或和都能有消元后的 异或和都能有消元后的 p 个 a[i] a[i]的异或 的异或 保证每一列只有一个1 消元后所有A[i]抑或起来就是答案 #include <cstdio> #include <cstring> #inclu

关于高斯消元解决xor问题的总结

我觉得xor这东西特别神奇,最神奇的就是这个性质了 A xor B xor B=A 这样就根本不用在意重复之类的问题了 关于xor的问题大家可以去膜拜莫队的<高斯消元解XOR方程组>,里面写的很详细 我来扯两道bzoj上的例题好了 bzoj2115,求1-N最长xor路径,根据那个神奇的性质,我们先随便找一条1-n的路径作为标准路径 任意一条1-N的路径都等价于标准路径和某些环的xor 怎么找环?很简单,bfs下去,设d[x]表示1到x的一条路径xor值,如果到一条边x-->y时y已经访

NEFU 504 new Flip Game (高斯消元)

题目链接 题解:和 poj1753Filp game 差不多,区别在于t组数据并且翻转的时候多了一个左上角. #include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <queue> #include <vector> #include <map> #includ

高斯消元与xor方程组

for(i=1;i<=n;i++) { for(j=i+1;j<=n;j++) if(a[j]>a[i]) swap(a[i],a[j]); if(!a[i]) break; for(j=60;j>=0;j--) if(a[i]>>j&1) { for(k=1;k<=n;k++) if(i!=k && (a[k]>>j&1)) a[k]^=a[i]; break; } } 对着这个代码思(dan)考(teng)了一星期.

poj 1753 Flip Game 高斯消元

题目链接 4*4的格子, 初始为0或1, 每次翻转一个会使它四周的也翻转, 求翻转成全0或全1最少的步数. #include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include &

poj 3185 The Water Bowls 高斯消元枚举变元

题目链接 给一行0 1 的数, 翻转一个就会使他以及它左右两边的都变, 求最少多少次可以变成全0. 模板题. #include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include

BZOJ 2466 [中山市选2009]树(高斯消元)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2466 [题目大意] 给定一棵树,每个节点有一盏指示灯和一个按钮.如果节点的按扭被按了, 那么该节点的灯会从熄灭变为点亮(当按之前是熄灭的),或者从点亮到熄灭 并且该节点的直接邻居也发生同样的变化.开始的时候,所有的指示灯都是熄灭的. 请编程计算最少要按多少次按钮,才能让所有节点的指示灯变为点亮状态. [题解] 高斯消元枚举自由变元回代. [代码] #include <cstdio>

POJ 2947-Widget Factory(高斯消元解同余方程式)

题目地址:id=2947">POJ 2947 题意:N种物品.M条记录,接写来M行,每行有K.Start,End,表述从星期Start到星期End,做了K件物品.接下来的K个数为物品的编号. 此题注意最后结果要调整到3-9之间. 思路: 非常easy想到高斯消元. 可是是带同余方程式的高斯消元,開始建立关系的时候就要MOD 7 解此类方程式时最后求解的过程要用到扩展gcd的思想,举个样例,假设最后得到的矩阵为: 1  1   4 0  6   4 则6 * X2 % 7= 4 % 7  则