poj 3185 The Water Bowls(高斯消元)

The Water Bowls

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 4352   Accepted: 1721

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

USACO 2006 January Bronze

高斯消元的简单题:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;

int a[24][24],x[24];
int equ,var;//方程数和变元数

void Debug()
{
    for(int i=0;i<equ;i++)
    {
        for(int j=0;j<=var;j++)
            printf("%d ",a[i][j]);
        puts("");
    }
    puts("");
}

int gauss()
{
    int max_r,col=0;
    for(int i=0;i<equ&&col<var;i++,col++)
    {
        max_r=i;
        for(int j=i+1;j<equ;j++)
        {
            if(a[j][col]>a[max_r][col]) max_r=j;
        }
        if(max_r!=i)
        {
            for(int k=0;k<=var;k++)
            {
                swap(a[i][k],a[max_r][k]);
            }
        }
        if(a[i][col]==0)
        {
            i--;
            continue;
        }

        for(int j=i+1;j<equ;j++)
        if(i!=j&&a[j][col])
        {
            for(int k=col;k<=var;k++)
            a[j][k]=a[i][k]^a[j][k];
        }
    }

    //Debug();
    for(int i=equ-1;i<equ;i++)
    if(a[i][var]) return -1;

    int ans=100,sum=0;
    for(int k=0;k<=1;k++)
    {
       x[equ-1]=(k&1)>0?1:0;
       sum=0;
       for(int i=equ-2;i>=0;i--)
       {
        int temp=a[i][var];
        for(int j=i+1;j<var;j++)
        {
            temp-=a[i][j]*x[j];
        }
        x[i]=temp/a[i][i];
       }
       for(int i=0;i<var;i++)
       if(x[i]%2!=0)
       {
           sum++;
       }

       //printf("  sum:%d\n",sum);
       ans=min(ans,sum);
    }
    return ans;
}

void init()
{
    memset(a,0,sizeof(a));
    memset(x,0,sizeof(x));
    for(int i=0;i<20;i++)
    {
        if(i!=0) a[i][i-1]=1;
        if(i!=19) a[i][i+1]=1;
        a[i][i]=1;
    }
    //Debug();
}
int main()
{
    equ=var=20;
    int t;
    while(scanf("%d",&t)!=EOF)
    {
        init();
        a[0][var]=t;
        for(int i=1;i<=19;i++)
        {
            scanf("%d",&a[i][var]);
        }
        int ans=gauss();
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-08-07 17:00:32

poj 3185 The Water Bowls(高斯消元)的相关文章

POJ 3185 The Water Bowls 高斯消元

高斯消元+位运算枚举自由变元 #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <set> #include <bitset> #include <queue> #include <stack> #include <string> #include <iostream> #i

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

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

poj3185--The Water Bowls(高斯消元问题3)

The Water Bowls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4623   Accepted: 1812 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

POJ 1681---Painter&#39;s Problem(高斯消元)

POJ   1681---Painter's Problem(高斯消元) Description There is a square wall which is made of n*n small square bricks. Some bricks are white while some bricks are yellow. Bob is a painter and he wants to paint all the bricks yellow. But there is something

POJ 1681 Painter&#39;s Problem (高斯消元)

题目地址:POJ 1681 跟前两题几乎一模一样的...不多说了.高斯消元+自由元枚举. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include &

POJ 1753 Flip Game (高斯消元 枚举自由变元求最小步数)

题目链接 题意:4*4的黑白棋,求把棋全变白或者全变黑的最小步数. 分析:以前用状态压缩做过. 和上题差不多,唯一的不同是这个终态是黑棋或者白棋, 但是只需要把给的初态做不同的两次处理就行了. 感觉现在还只是会套模板,不能独立的思考,好伤心.... 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath&g

POJ 2947 Widget Factory (高斯消元 判多解 无解 和解集 模7情况)

题目链接 题意: 公司被吞并,老员工几乎全部被炒鱿鱼.一共有n种不同的工具,编号1-N(代码中是0—N-1), 每种工具的加工时间为3—9天 ,但是现在老员工不在我们不知道每种工具的加工时间,庆幸的是还保留着一些对工人制造工具的记录,对于每个老员工,他的记录包括,他开始工作的时间(在某个星期的星期几),被炒鱿鱼的时间(某个星期的星期几),在第几个星期不知道.....在这段时间里,他正好加工了k件物品,给出了这k件物品的编号.我们要做的就是通过这些记录,来确定每种工具的加工时间是多少. 分析: 对

POJ 1222 extended lights out 高斯消元 板子题

题目链接:http://poj.org/problem?id=1222 题目描述:其实就是开关问题, 按下按钮会影响当前和周围的四个按钮, 问关闭所有灯的方案 解题思路:以前用搜索做过, 那时候是刚刚接触ACM的时候, 当时劲头真足啊, 这个解释的很好:http://blog.csdn.net/u013508213/article/details/47263183 代码: #include <iostream> #include <cstdio> #include <cstr

POJ 1222【异或高斯消元|二进制状态枚举】

题目链接:[http://poj.org/problem?id=1222] 题意:Light Out,给出一个5 * 6的0,1矩阵,0表示灯熄灭,反之为灯亮.输出一种方案,使得所有的等都被熄灭. 题解:首先可以用高斯消元来做,对于每个点,我们列出一个方程,左边是某个点和它相邻的点,他们的异或值等于右边的值(灯亮为1 ,灯灭为0),然后求一个异或高斯消元就可以了.可以用bitset优化,或者__int128优化(其实unsigned就可以了). 还可以枚举第一行的按开关的状态共有1<<6中状态