题意

游戏“The Pilots Brothers:跟随有条纹的大象”有一个玩家需要打开冰箱的任务。

冰箱门上有16个把手。每个手柄可以处于以下两种状态之一:打开或关闭。只有当所有把手都打开时,冰箱才会打开。手柄表示为矩阵4х4。您可以在任何位置[i,j](1≤i,j≤4)更改句柄的状态。但是,这也会更改第i行中所有句柄的状态以及第j列中的所有句柄。

任务是确定打开冰箱所需的最小手柄切换次数。

思路

一个和“费解的开关”,"棋盘翻转",这样的位运算的题目很像,只不过这次一次翻转1行+1列

其实可以用1个数就可以记录状态,但是我懒……

(其实是不会状压啦)

Code

#include<cstdio>
using namespace std;
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b) int x[], y[]; int map[][];
int ans=;
int ansX[],ansY[]; int read()
{
char ch = getchar();
while (ch!='-' && ch!='+') ch = getchar();
return ch=='-'?:;
} void build()
{
for(int i=;i<;i++)
for (int j = ; j < ; j++)
map[i][j] = read();
} void flip(int s)
{
int x1 = s / ;
int y1 = s % ;
for (int i = ; i < ; i++)
{
map[i][y1] ^= ;
map[x1][i] ^= ;
}
map[x1][y1] ^= ;
} bool check()
{
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
if (!map[i][j]) return ;
}
return ;
} void dfs(int s, int b)
{
if (check())
{
if (ans > b)
{
ans = b;
for (int i = ; i <= ans; i++)
ansX[i] = x[i], ansY[i] = y[i];
}
return;
} if (s >= ) return;
dfs(s + , b);
flip(s);
x[b + ] = s / + ;
y[b + ] = s % + ;
dfs(s + , b + );
flip(s);
return;
} int main()
{
build();
dfs(, );
printf("%d\n", ans);
for (int i = ; i <= ans; i++)
printf("%d %d\n", ansX[i], ansY[i]);
return ;
}

其他做法

博客上搜到的

放出来

注释也很详细了

用奇偶性做的

/*

参考高手的高效解法:
> 证明:要使一个为'+'的符号变为'-',必须其相应的行和列的操作数为奇数;可以证明,如果'+'位置对应的行和列上每一个位置都进行一次操作,则整个图只有这一'+'位置的符号改变,其余都不会改变.
> 设置一个4*4的整型数组,初值为零,用于记录每个点的操作数,那么在每个'+'上的行和列的的位置都加1,得到结果模2(因为一个点进行偶数次操作的效果和没进行操作一样,这就是楼上说的取反的原理),然后计算整型数组中一的
> 个数即为操作数,一的位置为要操作的位置(其他原来操作数为偶数的因为操作并不发生效果,因此不进行操作)
*********************************
此上证其可以按以上步骤使数组中值都为‘-’
********************************
在上述证明中将所有的行和列的位置都加1后,在将其模2之前,对给定的数组状态,将所有的位置操作其所存的操作数个次数,举例,如果a[i][j]==n,则对(i,j)操作n次,当所有的操作完后,即全为‘-’的数组。
其实就是不模2的操作,作了许多的无用功。
以上的操作次序对结果无影响,如果存在一个最小的步骤,则此步骤一定在以上操作之中。(简单说下:因为以上操作已经包含了所有可改变欲改变位置的操作了)
而模2后的操作是去掉了所有无用功之后的操作,此操作同样包含最小步骤。
但模2后的操作去掉任何一个或几个步骤后,都不可能再得到全为‘-’的。(此同样可证明:因为操作次序无影响,先进行最小步骤,得到全为‘-’,如果还剩下m步,则在全为‘-’的数组状态下进行这m步操作后还得到一个全为
‘-’的数组状态,此只能是在同一个位置进行偶数次操作,与前文模2后矛盾,所以m=0),因此模2后的操作即为最小步骤的操作。
*/
#include <iostream>
using namespace std; bool mark[][];
char s[][]; int main()
{
int i,j,k;
int ci[],cj[];
int nas = ;
memset(mark,,sizeof(mark));
for(i = ;i < ;i++)
cin >> s[i];
for(i = ;i < ;i++)
for(j = ;j < ;j++)
{
char c = s[i][j];
if(c == '+')
{
mark[i][j] = !mark[i][j];
for(k = ;k < ;k++)
{
mark[i][k] = !mark[i][k];
mark[k][j] = !mark[k][j];
}
} }
for(i = ;i < ;i++)
for(j = ;j < ;j++)
if(mark[i][j] == true)
{
ci[nas] = i + ;
cj[nas] = j + ;
nas ++;
}
printf("%d\n",nas);
for(i = ;i < nas;i++)
{
printf("%d %d\n",ci[i],cj[i]);
}
return ;
}

[POJ2965]The Pilots Brothers' refrigerator (搜索/位运算)的更多相关文章

  1. POJ2965——The Pilots Brothers' refrigerator

    The Pilots Brothers' refrigerator Description The game “The Pilots Brothers: following the stripy el ...

  2. POJ - 2965 The Pilots Brothers' refrigerator(压位+bfs)

    The game “The Pilots Brothers: following the stripy elephant” has a quest where a player needs to op ...

  3. poj2965 The Pilots Brothers' refrigerator

    题目链接:http://poj.org/problem?id=2965 分析:1.这道题和之前做的poj1753题目差不多,常规思路也差不多,但是除了要输出最少步数外,还要输出路径.做这道题的时候在怎 ...

  4. poj2965 The Pilots Brothers' refrigerator —— 技巧性

    题目链接:http://poj.org/problem?id=2965 题解:自己想到的方法是枚举搜索,结果用bfs和dfs写都超时了.网上拿别人的代码试一下只是刚好不超时的,如果自己的代码在某些方面 ...

  5. POJ 2965 The Pilots Brothers' refrigerator 位运算枚举

      The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 151 ...

  6. POJ 2965 The Pilots Brothers' refrigerator 暴力 难度:1

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16868 ...

  7. 枚举 POJ 2965 The Pilots Brothers' refrigerator

    题目地址:http://poj.org/problem?id=2965 /* 题意:4*4的矩形,改变任意点,把所有'+'变成'-',,每一次同行同列的都会反转,求最小步数,并打印方案 DFS:把'+ ...

  8. POJ 2965. The Pilots Brothers' refrigerator 枚举or爆搜or分治

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22286 ...

  9. POJ2965The Pilots Brothers' refrigerator(枚举+DFS)

    The Pilots Brothers' refrigerator Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22057 ...

随机推荐

  1. Dubbo2.6.5+Nacos注册中心(代替Zookeeper)

    在上一节的小栗子的基础上,只需要更改两个地方 第一个:父工程的pom依赖增加 <!-- Dubbo Nacos registry dependency --> <dependency ...

  2. velocity 新手用小常识--开源,简单易上手

    项目中经常用到的 .vm 后缀文件是什么? 基于 java 的 velocity 模版引擎的一种页面控制文件,是一些类似 html 语句和一种叫 VLT 的语句构成   velocity --美 [v ...

  3. Spring-Boot项目部署到单独tomcat运行

    前言: 本文是对学习SpringBoot过程中的笔记,拿最简单的项目进行部署,大家可以进行类比,文章最后会提供部署前和部署后的github地址,用代码做的笔记,可能会很乱,有兴趣的同学可以参考 正文: ...

  4. unix域字节流回射程序

    一.服务端程序 #include <stdio.h> #include <errno.h> #include <stdlib.h> #include <uni ...

  5. ES6走一波 数组的扩展

    Array flat 数组实例的扁平化方法(浏览器支持不佳) 建议使用 lodash的 flatten

  6. Django对于模型的数据操作

    一.引入模型的包 from myApp.models import Grades,Students 二.查询所有数据 #objecs是类的隐藏属性:类名.objects.all()可以查询所有数据 G ...

  7. Linux内存管理 (22)内存检测技术(slub_debug/kmemleak/kasan)【转】

    转自:https://www.cnblogs.com/arnoldlu/p/8568090.html 专题:Linux内存管理专题 关键词:slub_debug.kmemleak.kasan.oob. ...

  8. adb.exe 已停止工作解决办法

    最近因为工作原因,接触了下Android Studio,在使用真机调试的时候碰到了adb.exe 已经停止工作的错误. 虽然网上有很多和我一样的教程,但是我觉的还是记录一下自己的情况比较好,毕竟每个人 ...

  9. 快速搭建一个Spring Boot + MyBatis的开发框架

    前言:Spring Boot的自动化配置确实非常强大,为了方便大家把项目迁移到Spring Boot,特意总结了一下如何快速搭建一个Spring Boot + MyBatis的简易文档,下面是简单的步 ...

  10. 用JS实现实时显示系统时间

    废话我就不多说了,直接上图和代码了 效果图: 代码视图: 下面为大家附上代码,复制即可用: <!DOCTYPE html> <html lang="en"> ...