题意

游戏“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. host-only局域网络

    在网桥配置的情况下设置: 网桥配置链接 配置前: 配置后: vi /etc/sysconfig/network-scripts/ifcfg-eth0 这里是使用static静态配置,具体网络配置及声明 ...

  2. Hadoop基础-Hadoop的集群管理之服役和退役

    Hadoop基础-Hadoop的集群管理之服役和退役 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在实际生产环境中,如果是上千万规模的集群,难免一个一个月会有那么几台服务器出点故 ...

  3. kubernetes云平台管理实战: 滚动升级秒级回滚(六)

    一.nginx保证有两个版本 1.查看当前容器运行nginx版本 [root@k8s-master ~]# kubectl get pod -o wide NAME READY STATUS REST ...

  4. day18 集合框架(JCF)

    集合框架(JCF)java collections framework 框架:为了实现某一目的/功能而预先提供的一系列封装好的具有继承或实现关系的类与接口. 1.这种框架是高性能的,对基本类集(动态数 ...

  5. 关于使用 JSON.parse()报 VM141:1 Uncaught SyntaxError 的解决方案

    今天在使用ajax的后期,老师问我们怎么json解析对象,然后上百度搜了一下:大概有三个方式 var str = '{"name":"小明","age ...

  6. C++中数组作为形参进行传递(转)

    有两种传递方法,一种是function(int a[]); 另一种是function(int *a) 这两种两种方法在函数中对数组参数的修改都会影响到实参本身的值! 对于第一种,根据之前所学,形参是实 ...

  7. MySQL学习5 - 数据类型二.md

    一 字符类型 二 枚举类型和集合类型 一 字符类型 #官网:https://dev.mysql.com/doc/refman/5.7/en/char.html #注意:char和varchar括号内的 ...

  8. Ansible之Playbook详解、案例

    什么是playbook playbooks是一个不同于使用Ansible命令行执行方式的模式,其功能更强大灵活.简单来说,playbook是一个非常简单的配置管理和多主机部署系统,不同于任何已经存在的 ...

  9. linux文件系统初始化过程(3)---加载initrd(上)

    一.目的 本文主要讲述linux3.10文件系统初始化过程的第二阶段:加载initrd. initrd是一个临时文件系统,由bootload负责加载到内存中,里面包含了基本的可执行程序和驱动程序.在l ...

  10. typecho视频播放插件JWPlayer

    JWplayer for typecho是羽中大神开发并持续维护的一款插件,目前插件已经发布了8个版本,涵盖typecho0.8到1.0,插件基于原生的JWPlayer,可以说非常完美,详细使用方法在 ...