POJ 1681 (开关问题+高斯消元法)

题目链接http://poj.org/problem?id=1681

题目大意:一堆格子,或白或黄。每次可以把一个改变一个格子颜色,其上下左右四个格子颜色也改变。问最后使格子全部变黄,最少需要改变几个格子。

解题思路

与POJ 1222类似。

一共只有15*15个格子,设初始解向量黄为0,白为1.

对于每个开关,设其改变状态为x5,上下左右四个开关改变状态分别为x1,x2,x3,x4,

那么有方程x1^x2^x3^x4^x5^初始状态=0。

这样就有15*15个方程。解这15*15个线性方程组,就能得到每个格子的改变状态。

注意这里高斯消元的是一个开关矩阵,而不是黄白矩阵,也就是说,如果最后的解为0,不是表示这个格子为黄,而是这个格子相对于初始状态没有改变。

那么问题就来了,如何知道改变的最少格子?

其实很简单,在得到最终改变格子的状态后,统计一下里面的改变的格子数,也就是解为1的元,就是结果。

同时由于要判断无解情况,所以不能使用POJ 1222中那样的简略写法。

#include "cstdio"
#include "iostream"
#include "cstring"
using namespace std;
int ratio[230][230],dir[5][2]={0,0,-1,0,1,0,0,-1,0,1},T,n;
void reset()
{
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
           for(int k=0;k<5;k++)
    {
        int x=i+dir[k][0],y=j+dir[k][1];
        if(x>=0&&y>=0&&x<n&&y<n) ratio[i*n+j][x*n+y]=1;
    }
}
bool gauss()
{
    int i,j,k;
    for(i=0,j=0;i<n*n&&j<n*n;i++,j++)
    {
        k=i;
        for(;k<n*n;k++)
           if(ratio[k][j]) break;
        for(int t=j;t<=n*n;t++)
            if(i!=k) swap(ratio[i][t],ratio[k][t]);
        if(!ratio[i][j]) {i--;continue;}
        for(k=i+1;k<n*n;k++)
        {
            if(ratio[k][j])
                for(int t=j;t<=n*n;t++)
                   ratio[k][t]^=ratio[i][t];
        }
    }
    k=i;
    for(i=k; i<n*n; i++)
        if(ratio[i][n*n]) return false;
    for(i=k-1; i>=0; i--)
    {
        for(j=i+1; j<n*n; j++)
            ratio[i][n*n]^=(ratio[i][j]&&ratio[j][n*n]);
    }
    return true;
}
int main()
{
    //freopen("in.txt","r",stdin);
    char c;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        memset(ratio,0,sizeof(ratio));
        reset();
        for(int i=0;i<n*n;i++)
        {
            scanf(" %c",&c);
            if(c==‘w‘) ratio[i][n*n]=1;
            if(c==‘y‘) ratio[i][n*n]=0;
        }
        int ans=gauss();
        if(!ans) printf("inf\n");
        else
        {
            int ans=0;
            for(int i=0;i<n*n;i++)
                if(ratio[i][n*n]==1) ans++;
            printf("%d\n",ans);
        }
    }
}
13597338 neopenx 1681 Accepted 364K 16MS C++ 1651B 2014-11-04 13:14:49
时间: 2024-11-12 18:08:06

POJ 1681 (开关问题+高斯消元法)的相关文章

POJ 1222 (开关问题+高斯消元法)

题目链接: http://poj.org/problem?id=1222 题目大意:一堆开关,或开或关.每个开关按下后,周围4个方向开关反转.问使最后所有开关都关闭的,开关按法.0表示不按,1表示按. 解题思路: 一共只有5*6个开关. 对于每个开关,设其最终状态为x5,上下左右四个开关最终状态分别为x1,x2,x3,x4, 那么有方程x1^x2^x3^x4^x5^初始状态=0. 这样就有30个方程.解这30个线性方程组即可. 用高斯消元法来解方程组,变化如下: ①对于原本找列中绝对值最大这一步

poj 1830 开关问题 高斯消元法

开关问题 Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5854   Accepted: 2213 Description 有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关,如果为关就变为开.你的目标是经过若干次开关操作后使得最后N个开关达到一个特定的状态.对于任意一个开关,最多只能进行一次开关操作

poj 一类开关问题

这是一类开关问题,对于这类问题可以状态压缩枚举搞,也可以用高斯消元,当数据量比较大的时候高斯消元效率更高. poj 1222 状态压缩枚举第一行所有的翻转情况,从第二行开始依次递推即可. #include <iostream> #include <stdio.h> #include <string> #include <string.h> #include <algorithm> using namespace std; int dx[5]={0

POJ 1830 开关问题

简单的高斯消元取模,答案为2^自由变元的数量,但是题目的意思把I,J搞反了,坑爹... 开关问题 Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5425   Accepted: 2023 Description 有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关,如果为关就变为开.你的目标是经过若干次

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 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 1681 Painter&#39;s Problem (高斯消元)

题目链接 题意: 一个n*n 的木板 ,每个格子 都 可以 染成 白色和黄色,( 一旦我们对也个格子染色 ,他的上下左右 都将改变颜色): 给定一个初始状态 , 求将 所有的 格子 染成黄色 最少需要染几次?  若 不能 染成 输出 inf. 分析: 和1222差不多,唯一的区别是这个题还要求 最短的步数,其实只需要枚举一下最后的x[][]是否为1,即是否需要按下, 由于只有无解或者解唯一,因为按的顺序是没有影响的,所以只要是有解一定唯一,而且最短的情况是每个格子只按一次, 因为按两次以后就变为

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

http://poj.org/problem? id=1681 求最少经过的步数使得输入的矩阵全变为y. 思路:高斯消元求出自由变元.然后枚举自由变元,求出最优值. 注意依据自由变元求其它解及求最优值的方法. #include <stdio.h> #include <algorithm> #include <set> #include <map> #include <vector> #include <math.h> #include

POJ 1681 Painter&#39;s Problem 【高斯消元 二进制枚举】

任意门:http://poj.org/problem?id=1681 Painter's Problem Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7667   Accepted: 3624 Description There is a square wall which is made of n*n small square bricks. Some bricks are white while some bric