POJ 1681 Painter's Problem(高斯消元+枚举自由变元)
http://poj.org/problem?id=1681
题意:
有一块只有黄白颜色的n*n的板子,每次刷一块格子时,上下左右都会改变颜色,求最少刷几次可以使得全部变成黄色。
思路:
这道题目也就是要处理自由变元,如果自由变元为0,那么刷法是唯一的,如果有多个自由变元,那么可以有多种刷法,需要枚举处理。
借鉴了kuangbin大神的高斯消元模板,写得真的是好。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int maxn = + ; int n;
int equ,var; //equ个方程,var个变元
int x[maxn]; //解集
int a[maxn][maxn]; //矩阵
int free_x[maxn]; //存储自由变元
int free_num; //自由变元的个数 //返回值为-1表示无解,为0表示唯一解,否则返回自由变元个数
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 ;
} void print(int t)
{
if(t==-) puts("inf");
else if(t==)
{
int ans=;
for(int i=;i<n*n;i++) ans+=x[i];
printf("%d\n",ans);
}
else
{
//枚举自由变元
int ans=INF;
for(int i=;i<(<<t);i++)
{
int cnt=;
for(int j=;j<t;j++)
{
if(i&(<<j))
{
x[free_x[j]]=;
cnt++;
}
else x[free_x[j]]=;
}
for(int j=var-t-;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];
}
ans=min(ans,cnt);
}
printf("%d\n",ans);
}
} int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
memset(a,,sizeof(a)); for(int i=;i<n*n;i++)
{
a[i][i]=;
if(i/n) a[i-n][i]=;
if(i/n<n-) a[i+n][i]=;
if(i%n) a[i-][i]=;
if(i%n<n-) a[i+][i]=;
} char s[];
for(int i=;i<n;i++)
{
scanf("%s",s);
for(int j=;j<n;j++)
{
if(s[j]=='y') a[i*n+j][n*n]=;
else a[i*n+j][n*n]=;
}
} memset(x,,sizeof(x));
equ=var=n*n;
print(Gauss());
}
return ;
}
POJ 1681 Painter's Problem(高斯消元+枚举自由变元)的更多相关文章
- POJ 1681 Painter's Problem (高斯消元)
题目链接 题意:有一面墙每个格子有黄白两种颜色,刷墙每次刷一格会将上下左右中五个格子变色,求最少的刷方法使得所有的格子都变成yellow. 题解:通过打表我们可以得知4*4的一共有4个自由变元,那么我 ...
- POJ 1681 Painter's Problem [高斯消元XOR]
同上题 需要判断无解 需要求最小按几次,正确做法是枚举自由元的所有取值来遍历变量的所有取值取合法的最小值,然而听说数据太弱自由元全0就可以就水过去吧.... #include <iostream ...
- POJ 1753 Flip Game (高斯消元 枚举自由变元求最小步数)
题目链接 题意:4*4的黑白棋,求把棋全变白或者全变黑的最小步数. 分析:以前用状态压缩做过. 和上题差不多,唯一的不同是这个终态是黑棋或者白棋, 但是只需要把给的初态做不同的两次处理就行了. 感觉现 ...
- POJ 1681 高斯消元 枚举自由变元
题目和poj1222差不多,但是解法有一定区别,1222只要求出任意一解,而本题需要求出最少翻转次数.所以需要枚举自由变元,变元数量为n,则枚举的次数为1<<n次 #include < ...
- POJ 1681 Painter's Problem (高斯消元 枚举自由变元求最小的步数)
题目链接 题意: 一个n*n 的木板 ,每个格子 都 可以 染成 白色和黄色,( 一旦我们对也个格子染色 ,他的上下左右 都将改变颜色): 给定一个初始状态 , 求将 所有的 格子 染成黄色 最少需要 ...
- poj 3185 The Water Bowls 高斯消元枚举变元
题目链接 给一行0 1 的数, 翻转一个就会使他以及它左右两边的都变, 求最少多少次可以变成全0. 模板题. #include <iostream> #include <vector ...
- POJ 1681 Painter's Problem 【高斯消元 二进制枚举】
任意门:http://poj.org/problem?id=1681 Painter's Problem Time Limit: 1000MS Memory Limit: 10000K Total ...
- poj 1681 Painter's Problem(高斯消元)
id=1681">http://poj.org/problem? id=1681 求最少经过的步数使得输入的矩阵全变为y. 思路:高斯消元求出自由变元.然后枚举自由变元,求出最优值. ...
- poj 1681 Painter's Problem
Painter's Problem 题意:给一个n*n(1 <= n <= 15)具有初始颜色(颜色只有yellow&white两种,即01矩阵)的square染色,每次对一个方格 ...
随机推荐
- android加载gif图片
Android加载GIF图片的两种方式 方式一:使用第三开源框架直接在布局文件中加载gif 1.在工程的build.gradle中添加如下 buildscript { repositories { m ...
- 奇特的Local System权限(转载)
转载自:http://mp.weixin.qq.com/s?__biz=MzA3NTM1MzE4Nw==&mid=202597764&idx=1&sn=0cef1a40fb3c ...
- jmeter连接mysql数据库报错Cannot create PoolableConnectionFactory (Could not create connection to database server.)
今天在学习jmeter的jdbc取样器,发现在配置完JDBC Connection Configuration和JDBC Request后,点击运行.在查看结果树中显示响应数据: Cannot cre ...
- nginx 11个处理阶段 && nginx lua 8个处理阶段
1. nginx 11 个处理阶段 nginx实际把请求处理流程划分为了11个阶段,这样划分的原因是将请求的执行逻辑细分,各阶段按照处理时机定义了清晰的执行语义,开发者可以很容易分辨自己需要开发的模块 ...
- Andrew Ng-ML-第十六章-异常检测
1.问题动机 图1.飞机发动机检测例子 对飞机引擎的例子,如果选取了两个特征x1热量产生度,x2震动强度.并得到如下的图,如果有一个新的引擎来检测其是否正常,x_test,那么此时如果点落在和其他点正 ...
- numpy中arange()和linspace()区别
arange()类似于内置函数range(),通过指定开始值.终值和步长创建表示等差数列的一维数组,注意得到的结果数组不包含终值. linspace()通过指定开始值.终值和元素个数创建表示等差数列的 ...
- 2018-2019-2 网络对抗技术 20165324 Exp2: 后门原理与实践
2018-2019-2 网络对抗技术 20165324 Exp2: 后门原理与实践 课程学习: 后门 后门:是不经过正常认证流程而访问系统的通道,存在与编译器.操作系统.固件和应用中等等. 后门工作流 ...
- 55. Jump Game(贪心)
Given an array of non-negative integers, you are initially positioned at the first index of the arra ...
- 20155305乔磊2016-2017-2《Java程序设计》第五周学习总结
20155305乔磊2016-2017-2<Java程序设计>第五周学习总结 教材学习内容总结 try.catch 1.求平均数程序示例 import java.util.Scanner; ...
- R 简明教程
R 是一门统计语言.它有很多数据分析和挖掘程序包.可以用来统计.分析和制图. 你也可以在 LaTeX 文档中运行 R 命令. # 注释以 # 开始 # R 语言原生不支持 多行注释 # 但是你可以像这 ...