[POJ1753]Flip Game(异或方程组,高斯消元,枚举自由变量)
题目链接:http://poj.org/problem?id=1753
题意:同上。
这回翻来翻去要考虑自由变元了,假设返回了自由变元数量,则需要枚举自由变元。
/*
━━━━━┒ギリギリ♂ eye!
┓┏┓┏┓┃キリキリ♂ mind!
┛┗┛┗┛┃\○/
┓┏┓┏┓┃ /
┛┗┛┗┛┃ノ)
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┛┗┛┗┛┃
┓┏┓┏┓┃
┃┃┃┃┃┃
┻┻┻┻┻┻
*/
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <climits>
#include <complex>
#include <cassert>
#include <cstdio>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <ctime>
#include <set>
#include <map>
#include <cmath>
using namespace std; const int maxn = ;
int equ, var;
int a[maxn][maxn];
int x[maxn];
int free_x[maxn];
int free_num;
int ret1, ret2; int gauss() {
int max_r, col, k;
free_num = ;
for(k = , col = ; k < equ && col < var; k++, col++) {
max_r = k;
for(int i = k + ; i < equ; i++) {
if(abs(a[i][col]) > abs(a[max_r][col]))
max_r = i;
}
if(a[max_r][col] == ) {
k--;
free_x[free_num++] = col;
continue;
}
if(max_r != k) {
for(int j = col; j < var + ; j++)
swap(a[k][j], a[max_r][j]);
}
for(int i = k + ; i < equ; i++) {
if(a[i][col] != ) {
for(int j = col; j < var + ; j++) {
a[i][j] ^= a[k][j];
}
}
}
}
for(int i = k; i < equ; i++) {
if(a[i][col] != )
return -;
}
if(k < var) return var - k;
for(int i = var - ; i >= ; i--) {
x[i] = a[i][var];
for(int j = i + ; j < var; j++) {
x[i] ^= (a[i][j] & x[j]);
}
}
return ;
} char G[maxn][maxn];
int n; int main() {
// freopen("in", "r", stdin);
n = ;
var = equ = ;
ret1 = ret2 = ;
memset(a, , sizeof(a));
for(int i = ; i < n; i++) scanf("%s", G[i]);
for(int i = ; i < n; i++) {
for(int j = ; j < n; j++) {
if(G[i][j] == 'b') a[i*n+j][var] = ;
else a[i*n+j][var] = ;
}
}
for(int i = ; i < n; i++) {
for(int j = ; j < n; j++) {
int q = i * n + j;
a[q][q] = ;
if(i > ) a[(i-)*n+j][q] = ;
if(i < n - ) a[(i+)*n+j][q] = ;
if(j > ) a[i*n+j-][q] = ;
if(j < n - ) a[i*n+j+][q] = ;
}
}
int v1 = gauss();
if(v1 == -) ret1 = -;
else if(v1 != ) {
ret1 = maxn;
int tot = << v1;
for(int i = ; i < tot; i++) {
int cnt = ;
for(int j = ; j < v1; j++) {
if(i&(<<j)) {
x[free_x[j]] = ;
cnt++;
}
else x[free_x[j]] = ;
}
for(int j = var - v1 - ; j >= ; j--) {
int idx;
for(idx = j; idx < var; idx++) {
if(a[j][idx]) break;
}
x[idx] = a[j][var];
for(int l = idx + ; l < var; l++) {
if(a[j][l]) x[idx] ^= x[l];
}
cnt += x[idx];
}
ret1 = min(ret1, cnt);
}
}
else for(int i = ; i < var; i++) ret1 += x[i]; memset(a, , sizeof(a));
for(int i = ; i < n; i++) {
for(int j = ; j < n; j++) {
if(G[i][j] == 'w') a[i*n+j][var] = ;
else a[i*n+j][var] = ;
}
}
for(int i = ; i < n; i++) {
for(int j = ; j < n; j++) {
int q = i * n + j;
a[q][q] = ;
if(i > ) a[(i-)*n+j][q] = ;
if(i < n - ) a[(i+)*n+j][q] = ;
if(j > ) a[i*n+j-][q] = ;
if(j < n - ) a[i*n+j+][q] = ;
}
} int v2 = gauss();
if(v2 == -) ret2 = -;
else if(v2 != ) {
ret2 = maxn;
int tot = << v2;
for(int i = ; i < tot; i++) {
int cnt = ;
for(int j = ; j < v2; j++) {
if(i&(<<j)) {
x[free_x[j]] = ;
cnt++;
}
else x[free_x[j]] = ;
}
for(int j = var - v2 - ; j >= ; j--) {
int idx;
for(idx = j; idx < var; idx++) {
if(a[j][idx]) break;
}
x[idx] = a[j][var];
for(int l = idx + ; l < var; l++) {
if(a[j][l]) x[idx] ^= x[l];
}
cnt += x[idx];
}
ret2 = min(ret2, cnt);
}
}
else for(int i = ; i < var; i++) ret2 += x[i];
if(ret1==-&&ret2==-) puts("Impossible");
else if(v1==-) printf("%d\n", ret2);
else if(ret2==-) printf("%d\n", ret1);
else printf("%d\n", min(ret1, ret2));
return ;
}
[POJ1753]Flip Game(异或方程组,高斯消元,枚举自由变量)的更多相关文章
- 【HDU 5833】Zhu and 772002(异或方程组高斯消元)
300个最大质因数小于2000的数,选若干个它们的乘积为完全平方数有多少种方案. 合法方案的每个数的质因数的个数的奇偶值异或起来为0. 比如12=2^2*3,对应的奇偶值为01(2的个数是偶数为0,3 ...
- hdu 5833 Zhu and 772002 异或方程组高斯消元
ccpc网赛卡住的一道题 蓝书上的原题 但是当时没看过蓝书 今天又找出来看看 其实也不是特别懂 但比以前是了解了一点了 主要还是要想到构造异或方程组 异或方程组的消元只需要xor就好搞了 数学真的是硬 ...
- 3364 Lanterns (异或方程组高斯消元)
基本思路.首先构造一个n*(m+1)的矩阵,同时标记一个行数row,row从零开始,然后找出每一列第一个非零的数,和第row行互换, 然后对row到n行,异或运算.最终的结果为2^(m-row) #i ...
- 【HDU 5833】Zhu and 772002(异或方程组高斯消元讲解)
题目大意:给出n个数字a[],将a[]分解为质因子(保证分解所得的质因子不大于2000),任选一个或多个质因子,使其乘积为完全平方数.求其方法数. 学长学姐们比赛时做的,当时我一脸懵逼的不会搞……所以 ...
- POJ 1753 Flip game ( 高斯消元枚举自由变量)
题目链接 题意:给定一个4*4的矩阵,有两种颜色,每次反转一个颜色会反转他自身以及上下左右的颜色,问把他们全变成一种颜色的最少步数. 题解:4*4的矩阵打表可知一共有四个自由变元,枚举变元求最小解即可 ...
- NEFU 503 矩阵求解 (非01异或的高斯消元)
题目链接 中文题,高斯消元模板题. #include <iostream> #include <cstdio> #include <cmath> #include ...
- poj1222 EXTENDED LIGHTS OUT 高斯消元||枚举
Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 8481 Accepted: 5479 Description In an ...
- [题解](折半搜索/高斯消元枚举自由元)BZOJ_1770_Lights
状压,时间空间都不行,如果每次搜索一半就可以省下很多空间,用map记下每种状态的答案,最后再把两次的答案合并 然而正解是高斯消元解异或方程组,最后搜索自由元 #include<iostream& ...
- POJ 3185 The Water Bowls(高斯消元-枚举变元个数)
题目链接:http://poj.org/problem?id=3185 题意:20盏灯排成一排.操作第i盏灯的时候,i-1和i+1盏灯的状态均会改变.给定初始状态,问最少操作多少盏灯使得所有灯的状态最 ...
- POJ 1681 Painter's Problem(高斯消元+枚举自由变元)
http://poj.org/problem?id=1681 题意:有一块只有黄白颜色的n*n的板子,每次刷一块格子时,上下左右都会改变颜色,求最少刷几次可以使得全部变成黄色. 思路: 这道题目也就是 ...
随机推荐
- 【转】C#访问权限修饰符
C#访问权限修饰符 C#中类及类型成员修饰符有以下四类:public,private,protected,internal. public 类及类型成员的修饰符 private 类型成员 ...
- android记住密码和自动登陆
import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences ...
- ansible
3.1 配置 #vim /etc/ansible/hosts //定义主机,支持IP和域名,支持分组 [local] 127.0.0.1 [nginx] 192.168.0.10 ...
- linux与KVM虚拟里的windows实现文件共享
1.把windows系统里的共享文件设置为共享 2.在linux系统里 mount -t cifs //192.168.0.254/work /data/tmp -o username=test,pa ...
- https笔记
TCP提供了可靠的,面向连接的字节流服务. 1)应用数据分割成TCP认为适合发送的数据块,通过MSS(最大数据包长度)来控制. 2)重传机制 3)对首部和数据进行校验 4)TCP对收到的数据进行排序, ...
- uniq DEMO
测试数据: [weblogic@etp-mall-dev7][/tmp]$ cat msn.txt aaa bbb bbb ccc ccc ddd bbb eee aaa ccc bbb sss op ...
- Linux之查看CPU信息
# 查看逻辑CPU个数: # cat /proc/cpuinfo |grep "processor"|sort -u|wc -l 24 # 查看物理CPU个数: # grep &q ...
- android 动画总结
以下博文讲解比较详细,可查阅: http://www.360doc.com/content/13/0102/22/6541311_257754535.shtml 几个关键属性: setRepeatCo ...
- 在lua的string库和正则表达式
一.前提要了解一下lua 的string几个方法 1. string库中所有的字符索引从前往后是1,2,...;从后往前是-1,-2,... 2. string库中所有的function都不会直接操作 ...
- Spark函数
这张图不错!