任意门:http://poj.org/problem?id=3185

The Water Bowls
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 7676   Accepted: 3036

Description

The cows have a line of 20 water bowls from which they drink. The bowls can be either right-side-up (properly oriented to serve refreshing cool water) or upside-down (a position which holds no water). They want all 20 water bowls to be right-side-up and thus use their wide snouts to flip bowls.

Their snouts, though, are so wide that they flip not only one bowl but also the bowls on either side of that bowl (a total of three or -- in the case of either end bowl -- two bowls).

Given the initial state of the bowls (1=undrinkable, 0=drinkable -- it even looks like a bowl), what is the minimum number of bowl flips necessary to turn all the bowls right-side-up?

Input

Line 1: A single line with 20 space-separated integers

Output

Line 1: The minimum number of bowl flips necessary to flip all the bowls right-side-up (i.e., to 0). For the inputs given, it will always be possible to find some combination of flips that will manipulate the bowls to 20 0's.

Sample Input

0 0 1 1 1 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0

Sample Output

3

Hint

Explanation of the sample:

Flip bowls 4, 9, and 11 to make them all drinkable: 
0 0 1 1 1 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0 [initial state] 
0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0 [after flipping bowl 4] 
0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 [after flipping bowl 9] 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 [after flipping bowl 11]

Source

题意概括:

N个开关,打开一个开关相邻的开关状态会取反,给一个初始的所有开关状态,要求求出最小的改变开关的次数使得所有开关的状态为关闭;

解题思路:

构造增广矩阵类似于根据开关的关系构造有向图的邻接矩阵;

构造增广矩阵,高斯消元,枚举自由元(二进制枚举状态),寻找最小值;

AC code:

 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int MAXN = ;
int a[MAXN][MAXN]; //增广矩阵
int freeX[MAXN]; //自由元
int x[MAXN]; //解集
int equ, var;
int free_num;
int N; int Gauss()
{
int maxRow, col, k;
free_num = ;
for(k = , col = ; k < equ && col < var; k++, col++){
maxRow = k;
for(int i = k+; i < equ; i++){
if(abs(a[i][col]) > abs(a[maxRow][col])){
maxRow = i;
}
} if(a[maxRow][col] == ){
k--;
freeX[free_num++] = col;
continue;
}
if(maxRow != k){
for(int j = col; j < var+; j++){
swap(a[k][j], a[maxRow][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 solve()
{
int t = Gauss();
if(t == -){ //无解的情况,其实题目保证有解
printf("inf\n");
return;
}
else if(t == ){ //唯一解
int ans = ;
for(int i = ; i < N; i++){
ans += x[i];
}
printf("%d\n", ans);
return;
}
else{ //多解,枚举自由元
int ans = INF;
int tot = (<<t);
for(int i = ; i < tot; i++){
int cnt = ;
for(int j = ; j < t; j++){
if(i&(<<j)){
x[freeX[j]] = ;
cnt++;
}
else x[freeX[j]] = ;
} for(int j = var-t-; j >= ; j--){
int index;
for(index = j; index < var; index++)
if(a[j][index])
break;
x[index] = a[j][var]; for(int s = index+; s < var; s++)
if(a[j][s])
x[index] ^= x[s];
cnt += x[index];
}
ans = min(ans, cnt);
}
printf("%d\n", ans);
}
return;
} int main()
{
N = ;
equ = ;
var = ;
memset(a, , sizeof(a));
memset(x, , sizeof(x));
for(int i = ; i < N; i++){
a[i][i] = ;
if(i > ) a[i-][i] = ;
if(i < N-) a[i+][i] = ;
}
for(int i = ; i < N; i++){
scanf("%d", &a[i][N]);
}
solve();
return ;
}

POJ 3185 The Water Bowls 【一维开关问题 高斯消元】的更多相关文章

  1. POJ 3185 The Water Bowls(高斯消元-枚举变元个数)

    题目链接:http://poj.org/problem?id=3185 题意:20盏灯排成一排.操作第i盏灯的时候,i-1和i+1盏灯的状态均会改变.给定初始状态,问最少操作多少盏灯使得所有灯的状态最 ...

  2. poj 3185 The Water Bowls

    The Water Bowls 题意:给定20个01串(最终的状态),每个点变化时会影响左右点,问最终是20个0所需最少操作数? 水题..直接修改增广矩阵即可:看来最优解不是用高斯消元(若是有Gaus ...

  3. POJ 3185 The Water Bowls (高斯消元)

    题目链接 题意:翻译过来就是20个0或1的开关,每次可以改变相邻三个的状态,问最小改变多少次使得所有开关都置为0,题目保证此题有解. 题解:因为一定有解,所以我们可以正序逆序遍历两次求出较小值即可.当 ...

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

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

  5. POJ - 1681: Painter's Problem (开关问题-高斯消元)

    pro:开关问题,同上一题. 不过只要求输出最小的操作步数,无法完成输出“inf” sol:高斯消元的解对应的一组合法的最小操作步数. #include<bits/stdc++.h> #d ...

  6. POJ - 1222: EXTENDED LIGHTS OUT (开关问题-高斯消元)

    pro:给定5*6的灯的状态,如果我们按下一个灯的开关,它和周围4个都会改变状态.求一种合法状态,使得终状态全为关闭: sol:模2意义下的高斯消元. 终于自己手打了一个初级板子. #include& ...

  7. poj 3185 The Water Bowls(反转)

    Description The cows have a line of water bowls water bowls to be right-side-up and thus use their w ...

  8. POJ 3185 The Water Bowls (高斯消元 求最小步数)

    题目链接 题意:有20个数字,0或1.如果改变一个数的状态,它左右两边的两个数的状态也会变反.问从目标状态到全0,至少需要多少次操作. 分析: 和上一题差不多,但是比上一题还简单,不多说了,但是在做题 ...

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

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

随机推荐

  1. spring利用cors处理跨域问题

    参考 http://blog.csdn.net/isea533/article/details/50449907 写的很全面 http://blog.csdn.net/a317560315/artic ...

  2. nyoj1032——Save Princess——————【set应用】

    Save Princess 时间限制:1000 ms  |  内存限制:65535 KB 难度:2   描述 Yesterday, the princess was kidnapped by a de ...

  3. oracle 报错:ORA-02019 未找到数据库的连接说明

    一.问题描述 我之前连的是别的数据库,现在更换了数据库的连接,然后就报了如下的错误: 我使用的是NHibernate,我找到映射文件后发现我用了dblink,代码中table="COM_OR ...

  4. bzoj 4574: [Zjoi2016]线段树

    Description 小Yuuka遇到了一个题目:有一个序列a_1,a_2,?,a_n,q次操作,每次把一个区间内的数改成区间内的最大值,问 最后每个数是多少.小Yuuka很快地就使用了线段树解决了 ...

  5. 深入理解JavaScript系列(12):变量对象(Variable Object)

    介绍 JavaScript编程的时候总避免不了声明函数和变量,以成功构建我们的系统,但是解释器是如何并且在什么地方去查找这些函数和变量呢?我们引用这些对象的时候究竟发生了什么? 原始发布:Dmitry ...

  6. Spring mvc框架下使用kaptcha生成验证码

    1.下载jar包并导入. kaptcha-2.3.2.jar 2.spring 配置文件 applicationContext.xml. <bean id="captchaProduc ...

  7. 调试.NET程序OutOfMemoryException (转载)

    原文地址:http://blog.csdn.net/directionofear/article/details/8009427 应用程序调试,需要有个常规的调试思路,应对各类问题最基本的调试手段是什 ...

  8. 进程和程序(Process and Program)

    原出处:http://oss.org.cn/kernel-book/ch04/4.1.htm ----------------------------------个人理解分割线------------ ...

  9. abc098D Xor Sum 2(two point)

    题意 题目链接 给出一个序列,求出有多少区间满足\(A[l] \oplus A[l+1] \oplus \dots \oplus A[r] = A[l] + A[l + 1] +\dots+ A[r] ...

  10. javascript对象(2)

    这个对象,不是那个对象.续更第二篇.. 昨天说了对象的基本概念以及创建,今天来说一下它的其他方法: 1.访问属性的两种方式:点语法.[]语法 var dog =new Object(); dog.na ...