POJ 3185 The Water Bowls (Gaussian elimination method, enumeration free variable), pojbowls
Question:
The Water Bowls
Time Limit:1000 MS |
|
Memory Limit:65536 K |
Total Submissions:5013 |
|
Accepted:1960 |
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 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0 [initial state]
0 0 0 0 0 0 1 1 1 1 1 0 0 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 0 [after flipping bowl 11]
Source
USACO 2006 January Bronze
There are 20 bowls. If you flip a bowl together with the bowl next to him, you can flip the bowl to the front at least a few times.
Idea: This question is very similar to POJ1753. First Use Gaussian elimination method to find the free variable, and then enumerate to find the minimum value.
Code:
# Include <cstdlib> # include <cctype> # include <cstring> # include <cstdio> # include <cmath> # include <climits> # include <algorithm> # include <vector> # include <string> # include <iostream> # include <sstream> # include <map> # include <set> # include <queue> # include <stack> # include <fstream> # include <numeric> # include <iomanip> # include <bitset> # include <list> # include <stdexcept> # include <functional> # include <utility> # I Nclude <ctime> using namespace std; # define PB push_back # define MP make_pair # define REP (I, x, n) for (int I = x; I <(n ); ++ I) # define FOR (I, l, h) for (int I = (l); I <= (h); ++ I) # define FORD (I, h, l) for (int I = (h); I> = (l); -- I) # define SZ (X) (int) (X ). size () # define ALL (X ). begin (), (X ). end () # define RI (X) scanf ("% d", & (X) # define RII (X, Y) scanf ("% d ", & (X), & (Y) # define RIII (X, Y, Z) scanf ("% d", & (X ), & (Y), & (Z)) # Define DRI (X) int (X); scanf ("% d", & X) # define DRII (X, Y) int X, Y; scanf ("% d", & X, & Y) # define DRIII (X, Y, Z) int X, Y, Z; scanf ("% d", & X, & Y, & Z) # define OI (X) printf ("% d", X ); # define RS (X) scanf ("% s", (X) # define MS0 (X) memset (X), 0, sizeof (X ))) # define MS1 (X) memset (X),-1, sizeof (X) # define LEN (X) strlen (X) # define F first # define S second # define Swap (a, B) (a ^ = B, B ^ = a, a ^ = B) # defi Ne Dpoint strcut node {int x, y} # define cmpd int cmp (const int & a, const int & B) {return a> B ;} /* # ifdef HOME freopen ("in.txt", "r", stdin); # endif */const int MOD = 1e9 + 7; typedef vector <int> VI; typedef vector <string> VS; typedef vector <double> VD; typedef long LL; typedef pair <int, int> PII; // # define HOMEint Scan () {int res = 0, ch, flag = 0; if (ch = getchar () = '-') // judge whether positive or negative flag = 1; else if (ch> = '0 '&& Ch <= '9') // obtain the complete number res = ch-'0'; while (ch = getchar ()> = '0' & ch <= '9') res = res * 10 + ch-'0'; return flag? -Res: res ;} /* -------------- PLEASE---DO---NOT---HACK--ME ------------------ */const int MAXN = 50; int a [MAXN] [MAXN]; // The Augmented Matrix int x [MAXN]; // the solution set int free_x [MAXN]; // mark whether the variable is uncertain./* void Debug (void) {int I, j; for (I = 0; I <equ; I ++) {for (j = 0; j <var + 1; j ++) {cout <a [I] [j] <";}cout <endl ;} cout <endl;} */inline int gcd (int a, int B) {int t; while (B! = 0) {t = B; B = a % B; a = t;} return a;} inline int lcm (int a, int B) {return a/gcd (a, B) * B; // first remove and then take anti-overflow} // Gaussian elimination method for solving the equations (Gauss-Jordan elimination ). (-2 indicates a floating point solution, but no integer solution. //-1 indicates no solution, 0 indicates a unique solution, greater than 0 indicates an infinite solution, and returns the number of free variables) // There are equ equations and var variables. Number of rows in the augmented matrix is equ, 0 to equ-1, number of columns is var + 1, 0 to var.int Gauss (int equ, int var) {int I, j, k; int max_r; // the row with the largest absolute value of the current column. int col; // The int ta, tb; int LCM; int temp; int free_x_num; int free_index; for (int I = 0; I <= var; I ++) {x [I] = 0; free_x [I] = 0;} free_x_num = 0; // converts it to a step array. col = 0; // The currently processed column for (k = 0; k <equ & col <var; k ++, col ++) {// enumerate the currently processed rows. // find the row with the largest absolute value of the col column element and swap it with row k. (to reduce the error during Division) max_r = k; for (I = k + 1; I <equ; I ++ ){ If (abs (a [I] [col])> abs (a [max_r] [col]) max_r = I;} if (max_r! = K) {// exchange with row k. for (j = k; j <var + 1; j ++) swap (a [k] [j], a [max_r] [j]);} if (a [k] [col] = 0) {// indicates that the column k contains all 0, and the next column of the current row is processed. k --; free_x [free_x_num ++] = col; continue ;}for (I = k + 1; I <equ; I ++) {// enumerate the rows to be deleted. if (a [I] [col]! = 0) {LCM = lcm (abs (a [I] [col]), abs (a [k] [col]); ta = LCM/abs (a [I] [col]); tb = LCM/abs (a [k] [col]); if (a [I] [col] * a [k] [col] <0) tb =-tb; // if the difference is an addition for (j = col; j <var + 1; j ++) {a [I] [j] = a [I] [j] ^ a [k] [j] ;}} // Debug (); // 1. solution-free: the simplified augmented array exists (0, 0 ,..., a) such a row (! = 0 ). for (I = k; I <equ; I ++, record exchange. if (a [I] [col]! = 0) return-1;} // 2. infinite solution: In the augmented array of var * (var + 1), (0, 0 ,..., 0) This indicates that no strict upper triangle array is formed. // The number of rows displayed is the number of free yuan. // first, there are at least var-k variables. return var-k; // The free variable has var-k. // 3. unique Solution: a strict upper triangle array is formed in the augmented array of var * (var + 1. // calculate the Xn-1, Xn-2... x0.} int main () {for (int I = 0; I <20; I ++) RI (a [I] [20]); for (int I = 0; I <20; I ++) {a [I] [I] = 1; if (I! = 0) a [I-1] [I] = 1; if (I! = 19) a [I + 1] [I] = 1;} int t = Gauss (20, 20); int tot = 1 <t; int ans = INT_MAX; for (int I = 0; I <tot; I ++) {int cnt = 0; MS0 (x); for (int j = 0; j <t; j ++) {if (I & (1 <j) {x [free_x [j] = 1; if (x [free_x [j]) cnt ++ }}for (int j = 19-t; j> = 0; j --) {int temp = a [j] [20]; for (int k = j + 1; k <20; k ++) {if (a [j] [k]) temp ^ = x [k];} x [j] = temp; if (x [j]) cnt ++;} ans = min (ans, cnt);} printf ("% d \ n ", ans); return 0 ;}
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.