Flip Game
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 45691   Accepted: 19590

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

题目链接:POJ 1753

跟POJ 1222一样,只是会出现自由变量,那么我们可以用二进制枚举他们的值(由于是开关只能为0或1),然后他们的值即ans数组,然后再在高斯消元最后的回代法中考虑进这些自由变量的枚举值,计算ans中1的个数,要做两次这样的操作,因为最后的状态可以是全黑也可以是全白。代码里用模2的普通消元运算来代替异或运算,方便当模版

代码:

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <sstream>
#include <numeric>
#include <cstring>
#include <bitset>
#include <string>
#include <deque>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 6;
int Mat[18][18], ans[18];
char pos[N][N];
int num; int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
int lcm(int a, int b)
{
return a / gcd(a, b) * b;
}
inline int id(const int &x, const int &y)
{
return (x - 1) * 4 + y;
}
int Gaussian(int neq, int nvar)
{
int ceq, cvar;
int i, j;
num = 0;
for (ceq = 1, cvar = 1; ceq <= neq && cvar <= nvar; ++ceq, ++cvar)
{
int teq = ceq;
for (i = ceq + 1; i <= neq; ++i)
if (Mat[i][cvar] > Mat[teq][cvar])
teq = i;
if (teq != ceq)
for (i = cvar; i <= nvar + 1; ++i)
swap(Mat[ceq][i], Mat[teq][i]);
if (!Mat[ceq][cvar])
{
--ceq;
++num;
continue;
}
for (i = ceq + 1; i <= neq; ++i)
if (Mat[i][cvar])
{
int LCM = lcm(Mat[i][cvar], Mat[ceq][cvar]);
int up = LCM / Mat[ceq][cvar];
int down = LCM / Mat[i][cvar];
for (j = cvar; j <= nvar + 1; ++j)
Mat[i][j] = (Mat[i][j] * down % 2 - Mat[ceq][j] * up % 2 + 2) % 2;
}
}
for (i = ceq; i <= neq; ++i)
if (Mat[i][cvar])
return INF;
int ret = INF;
int stcnt = 1 << num;
for (int st = 0; st < stcnt; ++st)
{
int cnt = 0;
for (i = 0; i < num; ++i)
ans[ceq + i] = ((1 << i) & st) ? 1 : 0;
for (i = neq - num; i >= 1; --i)
{
ans[i] = Mat[i][nvar + 1];
for (j = i + 1; j <= nvar; ++j)
ans[i] = ((ans[i] % 2 - Mat[i][j] * ans[j] % 2) + 2) % 2;
}
for (i = 1; i <= 16; ++i)
cnt += ans[i];
ret = min(ret, cnt);
}
return ret;
}
int main(void)
{
int i, j;
while (~scanf("%s", pos[1] + 1))
{
for (i = 2; i <= 4; ++i)
scanf("%s", pos[i] + 1);
CLR(Mat, 0);
CLR(ans, 0);
for (i = 1; i <= 4; ++i)
{
for (j = 1; j <= 4; ++j)
{
Mat[id(i, j)][id(i, j)] = 1;
Mat[id(i, j)][17] = (pos[i][j] == 'b');
if (i > 1)
Mat[id(i, j)][id(i - 1, j)] = 1;
if (i < 4)
Mat[id(i, j)][id(i + 1, j)] = 1;
if (j > 1)
Mat[id(i, j)][id(i, j - 1)] = 1;
if (j < 4)
Mat[id(i, j)][id(i, j + 1)] = 1;
}
}
int Ans = Gaussian(16, 16);
CLR(Mat, 0);
CLR(ans, 0);
for (i = 1; i <= 4; ++i)
{
for (j = 1; j <= 4; ++j)
{
Mat[id(i, j)][id(i, j)] = 1;
Mat[id(i, j)][17] = (pos[i][j] == 'w');
if (i > 1)
Mat[id(i, j)][id(i - 1, j)] = 1;
if (i < 4)
Mat[id(i, j)][id(i + 1, j)] = 1;
if (j > 1)
Mat[id(i, j)][id(i, j - 1)] = 1;
if (j < 4)
Mat[id(i, j)][id(i, j + 1)] = 1;
}
}
Ans = min(Ans, Gaussian(16, 16));
Ans == INF ? puts("Impossible") : printf("%d\n", Ans);
}
return 0;
}

POJ 1753 Flip Game(高斯消元+状压枚举)的更多相关文章

  1. POJ 1753 Flip game ( 高斯消元枚举自由变量)

    题目链接 题意:给定一个4*4的矩阵,有两种颜色,每次反转一个颜色会反转他自身以及上下左右的颜色,问把他们全变成一种颜色的最少步数. 题解:4*4的矩阵打表可知一共有四个自由变元,枚举变元求最小解即可 ...

  2. poj 1753 Flip Game 高斯消元

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

  3. loj2542 「PKUWC2018」随机游走 MinMax 容斥+树上高斯消元+状压 DP

    题目传送门 https://loj.ac/problem/2542 题解 肯定一眼 MinMax 容斥吧. 然后问题就转化为,给定一个集合 \(S\),问期望情况下多少步可以走到 \(S\) 中的点. ...

  4. AcWing 208. 开关问题 (高斯消元+状压)打卡

    有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关,如果为关就变为开. 你的目 ...

  5. POJ 1222【异或高斯消元|二进制状态枚举】

    题目链接:[http://poj.org/problem?id=1222] 题意:Light Out,给出一个5 * 6的0,1矩阵,0表示灯熄灭,反之为灯亮.输出一种方案,使得所有的等都被熄灭. 题 ...

  6. POJ 1830 开关问题 高斯消元,自由变量个数

    http://poj.org/problem?id=1830 如果开关s1操作一次,则会有s1(记住自己也会变).和s1连接的开关都会做一次操作. 那么设矩阵a[i][j]表示按下了开关j,开关i会被 ...

  7. A - The Water Bowls POJ - 3185 (bfs||高斯消元)

    题目链接:https://vjudge.net/contest/276374#problem/A 题目大意:给你20个杯子,每一次操作,假设当前是对第i个位置进行操作,那么第i个位置,第i+1个位置, ...

  8. POJ 1166 The Clocks 高斯消元 + exgcd(纯属瞎搞)

    依据题意可构造出方程组.方程组的每一个方程格式均为:C1*x1 + C2*x2 + ...... + C9*x9 = sum + 4*ki; 高斯消元构造上三角矩阵,以最后一个一行为例: C*x9 = ...

  9. POJ 2065 SETI(高斯消元)

    题目链接:http://poj.org/problem?id=2065 题意:给出一个字符串S[1,n],字母a-z代表1到26,*代表0.我们用数组C[i]表示S[i]经过该变换得到的数字.给出一个 ...

随机推荐

  1. 2018.2.6 JS-判断用户浏览器

    JS-判断用户浏览器 在判断用户使用的浏览器是否为PC还是移动设备,有时候项目中需要用到.可在需要的项目中当全局方法来使用. 判断代码 function getMoblieDevice(window) ...

  2. Linux 下MySQL数据库配置远程访问

    1. mysql -u root -p 第一次直接回车跳过密码 2. use mysql; 3.执行授权命令 GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDE ...

  3. web跨域及cookie相关知识总结

    原文:web跨域及cookie相关知识总结   之前对于跨域相关的知识一致都很零碎,正好现在的代码中用到了跨域相关的,现在来对这些知识做一个汇总整理,方便自己查看,说不定也可能对你有所帮助. 本篇主要 ...

  4. 《GPU高性能编程CUDA实战中文》中第四章的julia实验

    在整个过程中出现了各种问题,我先将我调试好的真个项目打包,提供下载. /* * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. ...

  5. C语言字符,字符串,字节操作常用函数

    strlen 这个函数是在 string.h 的头文件中定义的 它的函数原型是 size_t strlen( const char ); size_t 是一个无符号整型,是这样定义的 typedef ...

  6. 重温 JSP 与 Servlet

    Java Web使用SSH框架多了,很多基础的 JSP 与 Servlet 的东西都忘记了.最近在 JSP 标签 和 Struts2 包装的 Session 对象的混合使用时弄晕了,就翻书温习下. J ...

  7. git与github账号建立SSH连接

    第1步:创建SSH Key.在用户主目录下,(就是在你的工作空间一层)看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa和id_rsa.pub这两个文件,如果已经有了,可直接跳到下一步 ...

  8. list,tuple,set,dict汇总

      有序/无序 追加/删除元素 元素可/不可重复 元素类型 创建方式 List 有序 可追加删除追加:list.append(item),list.insert(index,item)删除:list. ...

  9. GoF23种设计模式之创建型模式之原型模式

    一.概述 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 二.适用性 1.当一个系统应该独立于它的产品创建.构成和表示的时候. 2.当要实例化的类是在运行时刻指定的时候,例如:通过动 ...

  10. python模块汇总练习

    模块练习 1.random模块 # print(random.random()) # print(random.randint(1,3)) #模拟随机验证码 def make_code(n=5): r ...