Poj2965 冰箱的开关

#include<iostream>
using namespace std;

int flag;
int step;
int loction[6][6];
int r[16] = { 0 };
int c[16] = { 0 };

void turn(int i, int j) //转换
{
    for (int q = 0; q < 4; q++)
    {
        loction[i][q] = !(loction[i][q]);
    }
    for (int p = 0; p < 4; p++)
    {
        if (p != i)
        {
            loction[p][j] = !(loction[p][j]);
        }
    }

}

int range()//判定表格是否全部一样
{
    int i, j;
    for (i = 0; i < 4; i++)
    {
        for (j = 0; j < 4; j++)
        {
            if (loction[i][j] != 1)
            {
                return 0;
            }
        }
    }
    return 1;
}

int DFS(int i, int j, int dp)//深搜(dp<=step)
{
    //对第dp次的转换作判断
    if (dp == step)
    {
        flag = range();
        return 0;
    }
    if (flag || i == 4)
    {
        return 1;
    }

    //没有以上两种可以直接退出函数的情况,
    //说明此时的dp<step,就进行第dp+1次的转换
    turn(i, j); 
    //对当前转换的主位置(i,j)作记录
    r[dp] = i+1;
    c[dp] = j + 1;

    //对第dp+1次的转换进行判断
    if (j < 3)
    {
        //判断的是第dp+1次时转换的turn(i,j),
        //如果判断成功,直接退出函数。
        //如果判断失败,要继续进行下一列(即j+1)的递归转换和判断
        //j+1不影响对第dp+1次转换的turn(i,j)的判断
        //因为在DFS()函数里,判断turn(i,j)的步骤总在turn(i,j+1)前面
        DFS(i, j+1, dp + 1);
    }
    else
    {
        //判断的是第dp+1次时转换的turn(i,j),
        //如果判断成功,直接退出函数。
        //如果判断失败,要继续进行下一行(即i+1)的递归转换和判断
        //i+1不影响对第dp+1次转换的turn(i,j)的判断
        //因为在DFS()函数里,判断turn(i,j)的步骤总在turn(i+1,j)前面
        DFS(i + 1, 0, dp+1);
    }

    turn(i, j);      //不符合条件,重新转换回来

    //第dp次时,表格恢复初始状态
    if (j < 3)
    {
        DFS(i, j + 1, dp );   //进行对下一列进行第dp次的转换()
    }
    else
    {
        DFS(i + 1, 0, dp);    //进行对下一行进行第dp次的转换
    }

    return 0;

}

int main()
{
    char tmp;
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            scanf("%c", &tmp);
            if (tmp == ‘-‘)
            {
                loction[i][j] = 1;
            }
            else
            {
                loction[i][j] = 0;
            }
        }
        getchar();    //不要遗忘
    }

    for (step = 0; step <= 16; step++)
    {
        flag = 0;
        DFS(0, 0, 0);
        if (flag)
            break;
    }
    if (flag)
    {
        cout << step << endl;
        for (int i = 0; i < step; i++)
        {
            cout << r[i] << " " << c[i] << endl;
        }
    }
    return 0;

}
时间: 2024-11-08 19:02:44

Poj2965 冰箱的开关的相关文章

The Pilots Brothers&#39; refrigerator - poj 2965

Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20325   Accepted: 7830   Special Judge Description The game “The Pilots Brothers: following the stripy elephant” has a quest where a player needs to open a refrigerator. There are 16 handle

poj2965 The Pilots Brothers&#39; refrigerator 枚举或DFS

http://poj.org/problem?id=2965 一.枚举每一个‘+’点,对该点和该点所在的同一行和同一列所有点进行操作,开关本身状态改变了7次,开关同一行.同一列的开关状态改变了4次,其他开关状态改变了2次. 然后,用一个数组存取每个操作,如果为奇数,则证明该点为必须点,否则为不必要的. 1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 char map[4][4]; 5 int ans[4

翻转问题(开关,开灯问题)求解技巧

转载自:http://blog.csdn.net/ac_hell/article/details/51077320 翻转问题技巧详解 例.给定一个01串,现有翻转规则:翻转某一个位置时其后面2个位置也会跟着翻转,也就是每次翻转都会翻转3个连续的位置.要将01串全部翻转为0,求最小的翻转次数 形似这类题的问题叫做翻转问题,也可以叫开关问题,对于这类题通常都会用到下面我要说的方法来解 ①.若某一个位置被翻转了n次,则其实际上被翻转了n%2次,因为翻转2k次相当与没翻转,翻转2k+1次相当于翻转了1次

松下 冰箱 维修

松下 冰箱 维修: 1\  广州市昇洋创科数码技术服务有限公司  综合服务中心 广州市番禺区沙头街西环路622号4街7号  511400   联系电话 :     020-84872335  , 84663112 电子邮箱 2\  广州市信星电器有限公司  综合服务中心 广东省广州市海珠区南田路563号泰山庙前3号   510070 联系电话\020-87765811    电子邮箱 3.广州市 广东家维电器有限公司 电话:020-84350888   地址:广州市海珠区昌岗中路167号 4.深

基于Redis bitmap实现开关配置功能

作者:zhanhailiang 日期:2014-12-21 bitmap api SETBIT key offset value 对key所储存的字符串值,设置或清除指定偏移量上的位(bit). 位的设置或清除取决于value参数,可以是0也可以是1. 当key不存在时,自动生成一个新的字符串值. 字符串会进行伸展(grown)以确保它可以将value保存在指定的偏移量上. 当字符串值进行伸展时,空白位置以0填充. offset参数必须大于或等于0,小于2^32(bit映射被限制在512MB之内

开关中断与cpsid/cpsie指令

在汇编代码中,CPSID   CPSIE  用于快速的开关中断. CPSID I ;PRIMASK=1, ;关中断 CPSIE I ;PRIMASK=0, ;开中断 CPSID CPSIE F F ;FAULTMASK=1, ;FAULTMASK=0 ;关异常 ;开异常 I:IRQ中断;    F:FIQ中断 最常见的这两个命令的使用处是在关中断.开中断的实现中,我们经常用的local_irq_save和local_irq_restore最终都是调用了以下两个实现,即关/开中断只是操作了CP

Android5.0以上系统的移动网络开关

笔者近期遇到一个非常有意思的bug,贴出来和大家分享下. 那是一个温暖的早晨,阳光晒得人非常舒服.一封bug邮件像一片叶子飘到我的邮箱. 一番交流.笔者确认负责的Widget开关在Android5.0以上系统没有作用.相信非常多做过移动网络开关的朋友都知道.传统的方法是在ConnectivityManager中通过反射两个方法setMobileDataEnabled和getMobileDataEnabled来控制移动网络开和关的. /** * Gets the value of the sett

Gym 100712I Bahosain and Digits(开关翻转问题)

http://codeforces.com/gym/100712/attachments 题意: 给出一串数字,每次选择连续的k个数字加上任意数(超过10就取余),最后要使得所有数字都相等,求最大的k. 思路: 开关翻转问题. 算法具体可以参考<挑战程序竞赛>常用技巧篇. 这道题目就是在枚举k的同时再枚举一下最后要转换成的数字即可. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring>

微信小程序组件解读和分析:十五、switch 开关选择器

switch 开关选择器组件说明: switch,开关选择器.只能选择或者不选.这种属于表单控件或者查询条件控件. switch 开关选择器示例代码运行效果如下: 下面是WXML代码: [XML] 纯文本查看 复制代码 ? 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 <view class="secti