POJ 3185 The Water Bowls 【一维开关问题 高斯消元】
任意门:http://poj.org/problem?id=3185
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 7676 | Accepted: 3036 |
Description
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
Output
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
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 【一维开关问题 高斯消元】的更多相关文章
- POJ 3185 The Water Bowls(高斯消元-枚举变元个数)
题目链接:http://poj.org/problem?id=3185 题意:20盏灯排成一排.操作第i盏灯的时候,i-1和i+1盏灯的状态均会改变.给定初始状态,问最少操作多少盏灯使得所有灯的状态最 ...
- poj 3185 The Water Bowls
The Water Bowls 题意:给定20个01串(最终的状态),每个点变化时会影响左右点,问最终是20个0所需最少操作数? 水题..直接修改增广矩阵即可:看来最优解不是用高斯消元(若是有Gaus ...
- POJ 3185 The Water Bowls (高斯消元)
题目链接 题意:翻译过来就是20个0或1的开关,每次可以改变相邻三个的状态,问最小改变多少次使得所有开关都置为0,题目保证此题有解. 题解:因为一定有解,所以我们可以正序逆序遍历两次求出较小值即可.当 ...
- POJ 1830 开关问题 高斯消元,自由变量个数
http://poj.org/problem?id=1830 如果开关s1操作一次,则会有s1(记住自己也会变).和s1连接的开关都会做一次操作. 那么设矩阵a[i][j]表示按下了开关j,开关i会被 ...
- POJ - 1681: Painter's Problem (开关问题-高斯消元)
pro:开关问题,同上一题. 不过只要求输出最小的操作步数,无法完成输出“inf” sol:高斯消元的解对应的一组合法的最小操作步数. #include<bits/stdc++.h> #d ...
- POJ - 1222: EXTENDED LIGHTS OUT (开关问题-高斯消元)
pro:给定5*6的灯的状态,如果我们按下一个灯的开关,它和周围4个都会改变状态.求一种合法状态,使得终状态全为关闭: sol:模2意义下的高斯消元. 终于自己手打了一个初级板子. #include& ...
- 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 ...
- POJ 3185 The Water Bowls (高斯消元 求最小步数)
题目链接 题意:有20个数字,0或1.如果改变一个数的状态,它左右两边的两个数的状态也会变反.问从目标状态到全0,至少需要多少次操作. 分析: 和上一题差不多,但是比上一题还简单,不多说了,但是在做题 ...
- poj 3185 The Water Bowls 高斯消元枚举变元
题目链接 给一行0 1 的数, 翻转一个就会使他以及它左右两边的都变, 求最少多少次可以变成全0. 模板题. #include <iostream> #include <vector ...
随机推荐
- 读取日志文件,搜索关键字,打印关键字前5行。yield、deque实例
from collections import deque def search(lines, pattern, history=5): previous_lines = deque(maxlen=h ...
- 牛客网Java刷题知识点之Map的两种取值方式keySet和entrySet、HashMap 、Hashtable、TreeMap、LinkedHashMap、ConcurrentHashMap 、WeakHashMap
不多说,直接上干货! 这篇我是从整体出发去写的. 牛客网Java刷题知识点之Java 集合框架的构成.集合框架中的迭代器Iterator.集合框架中的集合接口Collection(List和Set). ...
- 安装cloudermanager时出现org.spingframework.web.bind.***** host[] is not present at AnnotationMethodHandlerAdapter.java line 738 ****错误(图文详解)(博主推荐)
不多说,直接上干货! 首先,这个问题,写给需要帮助的朋友们,本人在此,搜索资料近半天,才得以解决.看过国内和国外,资料甚少.特此,写此博客,为了弥补此错误解决的资料少的缘故! 问题详解 解决办法 ...
- C#的split()分割字符串
简单的说: 在C#中 str.Split("===="); //这样是错误的,只能 str.Split('=');//参数只能是char类型的,不能是字符串的 如果非得要以字符串分 ...
- PHP中break及continue两个流程控制指令解析
<?php $arr = array( 'a' => '0a0', 'b' => '0b0', 'c' => '0c0', 'd' => '0d0', 'e' => ...
- maven pom.xml指定jdk
<plugins> <!-- 指定jdk --> <plugin> <groupId>org.apache.maven.plugins</grou ...
- 记自己的hexo个人博客
https://othercoding.github.io/
- 深入理解JavaScript系列(26):设计模式之构造函数模式
介绍 构造函数大家都很熟悉了,不过如果你是新手,还是有必要来了解一下什么叫构造函数的.构造函数用于创建特定类型的对象——不仅声明了使用的对象,构造函数还可以接受参数以便第一次创建对象的时候设置对象的成 ...
- java常用API之Calendar类
Calendar是日历类,该类将所有可能用到的时间信息封装为静态成员变量,方便获取. Calendar为抽象类,由于语言敏感性,Calendar类在创建对象时并非直接创建,而是通过静态方法创建,将语言 ...
- jQuery Ajax(异步改同步)
在实际使用中,我们经常会用的Ajax(异步加载,在不刷新整个网页的前提下对网页部分内容进行更新) 使用时,偶尔会遇上需要从一个接口中得到一个数组和数据对应的id,在另一个接口上再得到数据,最初写法如下 ...