poj 1753 Flip Game(高斯消元)

Flip Game

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 30805   Accepted: 13409

Description

Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 squares. One side of each piece is white and the other one is black and each piece is lying either it‘s black or white side up. Each round you 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 are chosen every round according to the following rules:

  1. Choose any one of the 16 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 are 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 is shown at the picture), then the field will 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 are to write a program that will 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" each that 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 from the given position. If the goal is initially achieved, then write 0. If it‘s impossible to achieve the goal, then write the word "Impossible"
(without quotes).

Sample Input

bwwb
bbwb
bwwb
bwww

Sample Output

4

高斯消元简单题:

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

int a[35][35],x[35];
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-4;i<equ;i++)
    if(a[i][var]) return -1;

    int ans=100,sum=0;
    for(int k=0;k<=15;k++)
    {
       x[equ-1]=(k&1)>0?1:0;x[equ-2]=(k&2)>0?1:0;x[equ-3]=(k&4)>0?1:0;x[equ-4]=(k&8)>0?1:0;
       //printf("%d%d%d%d\n",x[equ-1],x[equ-2],x[equ-3],x[equ-4]);
       sum=0;
       for(int i=equ-5;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<=15;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<4;i++)
    for(int j=0;j<4;j++)
    {
        if(i!=0) a[i*4+j][(i-1)*4+j]=1;
        if(i!=3) a[i*4+j][(i+1)*4+j]=1;
        if(j!=0) a[i*4+j][i*4+j-1]=1;
        if(j!=3) a[i*4+j][i*4+j+1]=1;
        a[i*4+j][i*4+j]=1;
    }
    //Debug();
}
int main()
{
    equ=var=16;
    char s[20],t[7];
    memset(s,0,sizeof(s));
    memset(t,0,sizeof(t));
    while(scanf("%s",s)!=EOF)
    {
        for(int i=0;i<3;i++)
        {
            scanf("%s",t);
            strcat(s,t);
        }
        init();
        for(int i=0;i<16;i++)
        {
            if(s[i]=='b') a[i][var]=1;
            else a[i][var]=0;
        }
        int ans1=gauss();

        init();
        for(int i=0;i<16;i++)
        {
            if(s[i]=='w') a[i][var]=1;
            else a[i][var]=0;
        }
        int ans2=gauss();

        if(ans1!=-1&&ans2!=-1)
            printf("%d\n",min(ans1,ans2));
        else if(ans1!=-1) printf("%d\n",ans1);
        else if(ans2!=-1) printf("%d\n",ans2);
        else printf("Impossible\n");
    }
    return 0;
}
时间: 2024-12-24 12:08:24

poj 1753 Flip Game(高斯消元)的相关文章

poj 1753 Flip Game 高斯消元

题目链接 4*4的格子, 初始为0或1, 每次翻转一个会使它四周的也翻转, 求翻转成全0或全1最少的步数. #include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include &

[ACM] POJ 2947 Widget Factory (高斯消元)

Widget Factory Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 4436   Accepted: 1502 Description The widget factory produces several different kinds of widgets. Each widget is carefully built by a skilled widgeteer. The time required to

poj 1830 开关问题 高斯消元

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump

POJ 1166 The Clocks 高斯消元 + exgcd(纯属瞎搞)

根据题意可构造出方程组,方程组的每个方程格式均为:C1*x1 + C2*x2 + ...... + C9*x9 = sum + 4*ki; 高斯消元构造上三角矩阵,以最后一个一行为例: C*x9 = sum + 4*k,exgcd求出符合范围的x9,其他方程在代入已知的变量后格式亦如此. 第一发Gauss,蛮激动的. #include <algorithm> #include <iostream> #include <cstring> #include <cstd

POJ 1830 开关问题 高斯消元,自由变量个数

http://poj.org/problem?id=1830 如果开关s1操作一次,则会有s1(记住自己也会变).和s1连接的开关都会做一次操作. 那么设矩阵a[i][j]表示按下了开关j,开关i会被操作一次,记得a[i][i] = 1是必须的,因为开关i操作一次,本身肯定会变化一次. 所以有n个开关,就有n条方程, 每个开关的操作次数总和是:a[i][1] + a[i][2] + ... + a[i][n] 那么sum % 2就代表它的状态,需要和(en[i] - be[i] + 2) % 2

poj 2947 Widget Factory (高斯消元,解模线性方程)

链接:poj 2947 题意:生产一些零件,已知零件种数,记录条数 记录只记录了某次生产从周几开始,周几结束,以及生产了哪些产品. 每件商品生产所需天数为3-9天. 求每样产品需要多少天才能完成. 若无解输出Inconsistent data. 有无穷解输出Multiple solutions. 有唯一解,输出其解 分析:根据题目所给信息,可以列出同余方程组,再根据高斯消元求解, 但还得判断是无解,无穷解,还是唯一解 1.系数矩阵的秩若与增广矩阵的秩不相等,则无解,否则有解 2.若有解,若增广矩

poj 2947 Widget Factory(高斯消元)

description The widget factory produces several different kinds of widgets. Each widget is carefully built by a skilled widgeteer. The time required to build a widget depends on its type: the simple widgets need only 3 days, but the most complex ones

Poj 2947 widget factory (高斯消元解同模方程)

题目连接: http://poj.org/problem?id=2947 题目大意: 有n种类型的零件,m个工人,每个零件的加工时间是[3,9],每个工人在一个特定的时间段内可以生产k个零件(可以相同种类,也可以不同种类),问每种零件生产一个出来需要的时间? 解题思路: 给出的时间段是从周几到周几,并没有给出具体的时间段,因此在计算过程中要进行取模,还有就是对每个零件要在题目要求的范围内进行枚举. ps:如果求出来的增广矩阵是n*n的,但是某个零件在[3,9]之间没有合理的解,也是无解的. 1

POJ 3532 Resistance(高斯消元+基尔霍夫定理)

[题目链接] http://poj.org/problem?id=3532 [题目大意] 给出n个点,一些点之间有电阻相连,求1~n的等效电阻 [题解] 有基尔霍夫定理:任何一个点(除起点和终点)发出的电流和与接收的电流和相等. 由ΣAi=0可以得到Σ(Ui-Uj)/Rij=0,Σ(U1-Uj)/R1j=1,Σ(Un-Uj)/Rnj=-1 我们设电流为1A,终点电势为0列关于电势的方程组,最后的等效电阻就是起点和终点的电势差除以总电流 [代码] #include <cstdio> #inclu

POJ 1222-EXTENDED LIGHTS OUT(高斯消元求解异或方程组)

题目地址:POJ 1222 题意:有一个5*6的矩阵,每个位置都表示按钮和灯,1表示亮,0表示灭.每当按下一个位置的按钮,它和它周围灯的状态全部翻转(题目中给出如何影响),问在这样的一个方阵中按下哪些按钮可以把整个方阵都变成灭的,这时1表示按了,0表示没按. #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <iostream>