POJ 1753 Flip Game(高斯消元+状压枚举)
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 45691 | Accepted: 19590 |
Description
- Choose any one of the 16 pieces.
- 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
Output
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(高斯消元+状压枚举)的更多相关文章
- POJ 1753 Flip game ( 高斯消元枚举自由变量)
题目链接 题意:给定一个4*4的矩阵,有两种颜色,每次反转一个颜色会反转他自身以及上下左右的颜色,问把他们全变成一种颜色的最少步数. 题解:4*4的矩阵打表可知一共有四个自由变元,枚举变元求最小解即可 ...
- poj 1753 Flip Game 高斯消元
题目链接 4*4的格子, 初始为0或1, 每次翻转一个会使它四周的也翻转, 求翻转成全0或全1最少的步数. #include <iostream> #include <vector& ...
- loj2542 「PKUWC2018」随机游走 MinMax 容斥+树上高斯消元+状压 DP
题目传送门 https://loj.ac/problem/2542 题解 肯定一眼 MinMax 容斥吧. 然后问题就转化为,给定一个集合 \(S\),问期望情况下多少步可以走到 \(S\) 中的点. ...
- AcWing 208. 开关问题 (高斯消元+状压)打卡
有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关,如果为关就变为开. 你的目 ...
- POJ 1222【异或高斯消元|二进制状态枚举】
题目链接:[http://poj.org/problem?id=1222] 题意:Light Out,给出一个5 * 6的0,1矩阵,0表示灯熄灭,反之为灯亮.输出一种方案,使得所有的等都被熄灭. 题 ...
- POJ 1830 开关问题 高斯消元,自由变量个数
http://poj.org/problem?id=1830 如果开关s1操作一次,则会有s1(记住自己也会变).和s1连接的开关都会做一次操作. 那么设矩阵a[i][j]表示按下了开关j,开关i会被 ...
- A - The Water Bowls POJ - 3185 (bfs||高斯消元)
题目链接:https://vjudge.net/contest/276374#problem/A 题目大意:给你20个杯子,每一次操作,假设当前是对第i个位置进行操作,那么第i个位置,第i+1个位置, ...
- POJ 1166 The Clocks 高斯消元 + exgcd(纯属瞎搞)
依据题意可构造出方程组.方程组的每一个方程格式均为:C1*x1 + C2*x2 + ...... + C9*x9 = sum + 4*ki; 高斯消元构造上三角矩阵,以最后一个一行为例: C*x9 = ...
- POJ 2065 SETI(高斯消元)
题目链接:http://poj.org/problem?id=2065 题意:给出一个字符串S[1,n],字母a-z代表1到26,*代表0.我们用数组C[i]表示S[i]经过该变换得到的数字.给出一个 ...
随机推荐
- 【BZOJ1040】[ZJOI2008] 骑士(基环外向树DP)
点此看题面 大致题意: 给你一片基环外向树森林,如果选定了一个点,就不能选择与其相邻的节点.求选中点的最大权值和. 树形\(DP\) 此题应该是 树形\(DP\) 的一个升级版:基环外向树\(DP\) ...
- 2018.10.05 TOPOI提高组模拟赛 解题报告
得分: \(100+5+100=205\)(真的是出乎意料) \(T1\):抵制克苏恩(点此看题面) 原题: [BZOJ4832][Lydsy1704月赛] 抵制克苏恩 应该还是一个比较简单的\(DP ...
- dojo中类的继承
类似于c# java等后台语言,在基于类的面向对象编程中,通常需要在子类中扩展某些父类的方法,这时可以在子类的方法中,先调用从父类继承的方法,然后再执行子类自定义的操作.凡是使用declare创建的类 ...
- js打印div指定区域内容
<script> function myPrint(obj){ var newWindow=window.open("打印窗口","_blank") ...
- 详解JVM工作原理和特点
在我们运行和调试Java程序的时候,经常会提到一个JVM的概念.本文将为大家讲解JVM工作原理和特点,希望对大家有所帮助. AD:网+线下沙龙 | 移动APP模式创新:给你一个做APP的理由>& ...
- Java连接MySQL数据库实现用户名密码的验证方法 Java语句中sql查询语句'' ""作用
//方法一,可以验证登录,但方法不实用.package com.swift; import java.sql.Connection; import java.sql.DriverManager; im ...
- 爬虫学习(三)——get请求参数解析
get请求: 用户输入搜索的内容,发送请求,将请求的内容保存起来. get请求的本质是在地址栏中输入参数进行的一种请求方式. 解析参数使用urllib.parse impo ...
- Java 对数组的筛选
在Java里面 一般对一个数组进行筛选,去剔除一些元素,一般做法是用临时数组来存储,把符合条件的元素加入到新数组中,虽然数组有移除的方法但是 是线程不安全的: 而用迭代器Iterator,可以在遍历的 ...
- 二十六、MySQL 临时表
MySQL 临时表 MySQL 临时表在我们需要保存一些临时数据时是非常有用的.临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间. 临时表在MySQL 3.23版本中添加,如 ...
- JAVA 同步实现原理
Synchronized的基本使用 Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法.Synchronized的作用主要有三个: 确保线程互斥的访问同步代码 保 ...