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 ...
随机推荐
- GraphQL 暂停
别人的文章 http://blog.csdn.net/imwebteam/article/details/53888708 Java 文档都打不开,已经在GitHub上提了 in README.md ...
- python_学生信息管理实例
"""提示:代码中的内容均被注释,请参考,切勿照搬""" """注意:代码切勿照搬,错误请留言指出" ...
- python 爬虫系列09-异步斗图来一波
斗图斗图,妈妈再也不怕我都不赢了 import requests from lxml import etree from urllib import request import os import ...
- JavaScript 浮点数及运算精度调整总结
JavaScript 浮点数及运算精度调整总结 JavaScript 只有一种数字类型 Number,而且在Javascript中所有的数字都是以IEEE-754标准格式表示的.浮点数的精度问题不是J ...
- 【转】CentOS6下安装mysql后,重置root密码方法
本文转自:CentOS6下安装mysql后,重置root密码方法 centos下安装mysql,居然不知道root用户密码,本想重装,不过还是先度娘了一些,发现这篇文章,刚好解决我的燃眉之急,太赞了. ...
- Java入门系列-06-运算符
这篇文章为你搞懂2个问题 java 中的常用运算符有哪些?如何使用? 这些运算符的运算优先级是怎样的? 算数运算符 明显是做数学运算的,包括以下符号: + 加法运算 敲一敲: public class ...
- js 中移动元素的方法
2017-12-13 19:59:24 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...
- 【OSI】网络协议模型
一.网络相关概念 IP地址: 主机 用于 路由寻址 用的数字标识 域名: 便于IP地址记忆 DNS: 通过注册的 域名 指向 ip 的服务 DDNS: 将用户的动态IP地址映射到一个固定的域名解析服 ...
- 归并排序——Java实现
一.排序思想 将两个或两个以上的一排序文件合并成一个有序文件的过程叫归并,而归并排序就是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用.将以有序的了序列合并,得到完全有序 ...
- 服务器LIUNX之如何解决矿机问题
点进来的基本都是遇到liunx变矿机的小伙伴吧(cpu运载300%) 卡的连终端都很难打开 开下来之后提示 大意是, 到xxx网站给钱了事, 不过基本这个网站基本也上不去, 要么是暴力破解, 要么是通 ...