POJ 1753 Flip Game (Gaussian elimination method, enumeration of free elements)

Source: Internet
Author: User
Tags rounds

Topic:

Flip Game
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 34731 Accepted: 15207

Description

Flip game is played on a rectangular 4×4 field with two-sided pieces placed on each of its squares. One side of each piece are white and the other one are black and each piece is lying either it's black or white side up. Each round your flip 3 to 5 pieces, thus changing the color of their upper side from black to white and vice versa. The pieces to be flipped is chosen every round according to the following rules:
    1. Choose any one of the pieces.
    2. Flip The chosen piece and also all adjacent pieces to the left, to the right, to the top, and to the bottom of the chosen Piece (if there is any).

Consider the following position as an example:

Bwbw
Wwww
Bbwb
Bwwb
Here ' B ' denotes pieces lying their black side up and ' w ' denotes pieces lying their white side up. If we choose to flip the 1st piece from the 3rd row (this choice was shown at the picture) and then the field would become:

Bwbw
bWWW
Wwwb
Wwwb
The goal of the game is to flip either all pieces white side up or all pieces black side up. You is to write a program, that would search for the minimum number of rounds needed to achieve this goal.

Input

The input consists of 4 lines with 4 characters "W" or "B" from each of the denote game field position.

Output

Write to the output file a single integer number-the minimum number of rounds needed to achieve the goal of the game fro M the given position. If The goal is initially achieved and then write 0. If it's impossible to achieve the goal and then write the word "impossible" (without quotes).

Sample Input

Bwwbbbwbbwwbbwww

Sample Output

4

Source

Northeastern Europe 2000

Test instructions: There is a 4*4 chess board with black and white pieces on it, and ask at least how many times you can make the chess pieces on the board black or white.

Idea: The data is very small, can be violent, but here with the Gaussian elimination method solution, the problem is that the minimum number of times required, so to enumerate the free variable. Assuming that there are k free elements, then all the cases have 1<<k, when the Gaussian elimination method is solved, the free variable is recorded, then all the cases are enumerated, and the equations are equ-k when solving the non-free variable elements.

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> #include <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) (x). Begin (), (x). End () #define RI (x) scanf ("%d", & (x)) #define RII (x, Y) scanf ("%d%d", & (X), & (Y)) # Define RIII (x, Y, z) scanf ("%d%d%d", & (X), & (Y), & (z)) #define DRI (x) int (x); scanf ("%d", &x) #define DRII (x, y) int X, y; scanf ("%d%d", &x, &y) #define DRIII (x, y, z) int x, y, Z; scanf ("%d%d%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#def  Ine Swap (A, B) (a ^= B, b ^= A, a ^= b) #define Dpoint strcut node{int x, y} #define CMPD int cmp (const int &AMP;A,CONST int    &AMP;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 Long ll;typedef pair<int,int> pii;//#define Homeint Scan () {int res = 0, ch, flag = 0;if (ch = getcha R ()) = = '-')//determine positive and negative flag = 1;else if (ch >= ' 0 ' && ch <= ' 9 ')//Get complete number res = CH-' 0 '; while ((ch = getchar ()) > = ' 0 ' && ch <= ' 9 ') res = res * + CH-' 0 '; return flag? -res:res;}/*---------------------Do----------HACK-----ME--------------------*/const int maxn=50;int A[MAXN][MAXN]    ;//augmented matrix int x[maxn];//solution int free_x[maxn];//tag is indeterminate variable void Debug (int equ,int var) {int I, J; for (i = 0, i < equ; i++) {for (j = 0, J < var + 1; j + +) {cout << a[i][j] <&l T        " ";    } 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; The inline int LCM (int a,int b) {return A/GCD (A, a) *b;//first divide and then multiply the anti-overflow}//Gaussian elimination method to solve the equation set (Gauss-jordan elimination). (-2 means that there is a floating-point solution, but no integer solution,//-1 represents no solution, 0 means the unique solution, greater than 0 is the infinite solution, and returns the number of free arguments)//There are equ equations, var variable element.    The number of augmented matrix rows is equ, 0 to Equ-1, and the number of columns is var+1, respectively, 0 to Var.int Gauss (int equ,int var) {int i,j,k;    int max_r;//The row with the largest absolute value for the current column.    int col;//the currently processed column 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; Converted to a stepped array.   col=0; The currently processed column for (k = 0;k < equ && Col < var;k++,col++) {//enumerates the currently processed rows.//The row that finds the largest absolute value of the col column element is exchanged with the K line.        To reduce the error when dividing) 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) {//is exchanged with line K.        for (j=k;j<var+1;j++) swap (a[k][j],a[max_r][j]);            } if (a[k][col]==0) {//indicates that the COL column K line below is all 0, then the next column of the current row is processed.            k--;            Free_x[free_x_num++]=col;        Continue            } for (i=k+1;i<equ;i++) {//enumerates 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;//, the case is added for (j=col;j<var+1;j++) {                A[I][J] = A[i][j]^a[k][j];    }}}}//debug (Equ,var); 1. The absence of solution: the existence of the augmented matrix of simplification(0, 0, ..., a) such a line (a! = 0).        for (i = k; i < equ; i++) {//For infinite solutions, if you want to determine which are free-variable, then the Exchange in the elementary row transformation will be affected, then the interchange should be recorded.    if (A[i][col]! = 0) return-1; }//2.    The case of Infinity: in the augmented array of Var * (var + 1) (0, 0, ..., 0) Such a line, that is to say, does not form a strict upper triangular array.    and the number of rows that appear is the number of free arguments.      if (K < Var)//{///First, the free variable has var-k, that is, the indeterminate variable has at least var-k.        Debug (Equ,var); return var-k;  There are var-k of free-variable elements. }//3.    The only solution: a strict upper triangular array is formed in the augmented array of Var * (var + 1). Calculate the Xn-1, Xn-2 ...   X0.        /* for (i = var-1; I >= 0; i--) {temp = A[i][var];        for (j = i + 1; j < var; j + +) {if (a[i][j]! = 0) Temp ^= a[i][j] && x[j]; } if (temp% a[i][i]! = 0) return-2;        Indicates that there is a floating-point number solution, but no integer solution.    X[i] = Temp/a[i][i]; } return 0;*/}char Mp[4][4];int main () {//freopen ("OUT.txt", "w", stdout), for (int i=0;i<4;i++) {for (int j=0;j<4;j    + +) scanf ("%c", &mp[i][j]);   printf ("%c", Mp[i][j]);}    printf ("\ n");    GetChar (); }ms0 (a); for (int i=0;i<4;i++) for (int j=0;j<4;j++) {int k=i*4+j;    if (mp[i][j]== ' B ') a[k][16]=0; else a[k][16]=1;}    for (int i=0;i<4;i++) for (int j=0;j<4;j++) {int t=i*4+j;    A[t][t]=1;    if (i!=0) a[(i-1) *4+j][t]=1;    if (i!=3) a[(i+1) *4+j][t]=1;    if (j!=0) a[i*4+ (j-1)][t]=1; if (j%4!=3) a[i*4+j+1][t]=1;} int Ans=gauss (16,16); if (ans==-1| | ans==-2) ans=int_max;else{/*if (ans==0) {for (INT i=0;i<16;i++) ans+=x[i];}        *//else//{int t=ans;        Ans=int_max;        int tot= (1&LT;&LT;T);               for (int i=0;i<tot;i++) {int cnt=0;                int index=i;               for (int j=0;j<t;j++) {x[free_x[j]]= (index&1);               if (X[free_x[j]]) cnt++;            index>>=1;                } for (int j=16-t-1;j>=0;j--) {int temp = a[j][16];                int tt=0; while (a[j][tt]==0)//tt++;        for (int k = j+1; k <; k++) {if (a[j][k]! = 0) temp ^= x[k]; }//if (temp% a[j][j]! = 0) return-2;        Indicates that there is a floating-point number solution, but no integer solution.        X[J] = Temp/a[j][j];            CNT+=X[J];            } ans=min (ANS,CNT);    }//}}ms0 (a); for (int i=0;i<4;i++) for (int j=0;j<4;j++) {int k=i*4+j;    if (mp[i][j]== ' B ') a[k][16]=1; else a[k][16]=0;}    for (int i=0;i<4;i++) for (int j=0;j<4;j++) {int t=i*4+j;    A[t][t]=1;    if (i!=0) a[(i-1) *4+j][t]=1;    if (i!=3) a[(i+1) *4+j][t]=1;    if (j!=0) a[i*4+ (j-1)][t]=1; if (j%4!=3) a[i*4+j+1][t]=1;} int Ans2=gauss (16,16); if (ans2==-1| |    ans2==-2) ans2=int_max;else{/*if (ans2==0) {for (INT i=0;i<16;i++) ans2+=x[i];}        else {*/int t=ans2;        Ans2=int_max;        int tot= (1&LT;&LT;T);                 for (int i=0;i<tot;i++) {int cnt=0;                int index=i;     for (int j=0;j<t;j++) {               x[free_x[j]]=index&1;                    if (X[free_x[j]]) cnt++;                index>>=1;              } for (int j=16-t-1;j>=0;j--) {int temp = a[j][16];               int tt=0;        while (a[j][tt]==0)//tt++;        for (int k = j+1; k <; k++) {if (a[j][k]! = 0) temp ^= x[k]; }//if (temp% a[j][j]! = 0) return-2;        Indicates that there is a floating-point number solution, but no integer solution.        X[J] = Temp/a[j][j];            CNT+=X[J];            } ans2=min (ANS2,CNT); }//}}int Res=min (ANS,ANS2); if (Res==int_max) {printf ("impossible\n");}        else printf ("%d\n", res); return 0;}



Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

POJ 1753 Flip Game (Gaussian elimination method, enumeration of free elements)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.