poj 1222  EXTENDED LIGHTS OUT

开关只有两种方案 按和不按,按两次相当于关

只用枚举第一排开关的按法即可,剩下的行为使上一排的灯全部关闭,按法可以确定,并且是唯一的。

最后检查最后一行是否都为0,都为0为可行的方案。  用位运算来实现。

#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std; char ol[], l[], r[];
int t; int getBit(char c, int i)
{
return & (c>>i);
} void setBit(char &c, int i, int v)
{
if (v) {
c |= ( << i);
}
else
c &= ~( << i);
} void FlipBit(char &c, int i)
{
c ^= ( << i);
} void output()
{
cout << "PUZZLE #" << t << endl;
for (int i = ; i < ; i++) {
for (int j = ; j < ; j++) {
cout << getBit(r[i], j);
if (j < )
cout << " ";
}
cout << endl;
}
} int main()
{
//freopen("1.txt", "r", stdin);
int T;
cin >> T;
for (t = ; t <= T; t++) {
for (int i = ; i < ; i++)
for (int j = ; j < ; j++) {
int s;
cin >> s;
setBit(ol[i], j, s);
} for (int n = ; n < ; n++) { //枚举第一列方案0~2^6-1
memcpy(l, ol, sizeof(ol));
int switchs = n; //当前行的开关状态
for (int i = ; i < ; i++) {
r[i] = switchs;
for (int j = ; j < ; j++) {
if (getBit(switchs, j)) {
if (j > )
FlipBit(l[i], j-);
FlipBit(l[i], j);
if (j < )
FlipBit(l[i], j+);
}
}
if (i < )
l[i+] ^=switchs;
switchs = l[i]; //i+1行灯的状态由第i行灯的状态决定
}
if (l[] == ) {
output();
break;
}
}
} return ;
}

特殊密码锁

描述

有一种特殊的二进制密码锁,由n个相连的按钮组成(n<30),按钮有凹/凸两种状态,用手按按钮会改变其状态。

然而让人头疼的是,当你按一个按钮时,跟它相邻的两个按钮状态也会反转。当然,如果你按的是最左或者最右边的按钮,该按钮只会影响到跟它相邻的一个按钮。

当前密码锁状态已知,需要解决的问题是,你至少需要按多少次按钮,才能将密码锁转变为所期望的目标状态。

输入两行,给出两个由0、1组成的等长字符串,表示当前/目标密码锁状态,其中0代表凹,1代表凸。输出至少需要进行的按按钮操作次数,如果无法实现转变,则输出impossible。

样例输入

011
000

样例输出

1

类似的思想,枚举第一个的状态,两种可能,那剩下的就可以唯一确定了,最后检查最后一位即可
#include <iostream>
#include <stdio.h>
#include <cstring>
#include <string>
using namespace std;
#define INF 0x3f3f3f3f
int src, des, r, t;
int ans; int getBit(int c, int i)
{
return & (c >> i);
} void setBit(int &c, int i, int v)
{
if (v)
c |= ( << i);
else
c &= ~( << i);
} void flipBit(int &c, int i)
{
c ^= ( << i);
} int main()
{
//freopen("1.txt", "r", stdin);
string a;
cin >> a;
int len = a.length();
for (int i = ; i < len; i++)
setBit(src, i, a[i]-''); cin >> a;
for (int i = ; i < len; i++)
setBit(des, i, a[i]-''); int Min, cnt;
for (int p = ; p < ; p++) {
Min = INF; cnt = ;
t = src;
if (p) {
flipBit(t, );
flipBit(t, );
cnt++;
}
for (int i = ; i < len; i++) {
if (getBit(t, i-) != getBit(des, i-)) {
cnt++;
flipBit(t, i);
if (i < len-)
flipBit(t, i+);
}
}
if (getBit(t, len-) == getBit(des, len-)) {
if (cnt < Min) {
Min = cnt;
ans = cnt;
}
}
}
if (Min == INF)
cout << "impossible";
else
cout << ans; return ;
}

poj 1166 拨钟问题

有9个时钟,排成一个3*3的矩阵。

|-------|    |-------|    |-------|
| | | | | | |
|---O | |---O | | O |
| | | | | |
|-------| |-------| |-------|
A B C |-------| |-------| |-------|
| | | | | |
| O | | O | | O |
| | | | | | | | |
|-------| |-------| |-------|
D E F |-------| |-------| |-------|
| | | | | |
| O | | O---| | O |
| | | | | | | |
|-------| |-------| |-------|
G H I
(图 1)

现在需要用最少的移动,将9个时钟的指针都拨到12点的位置。共允许有9种不同的移动。如下表所示,每个移动会将若干个时钟的指针沿顺时针方向拨动90度。

移动    影响的时钟

 1         ABDE
2 ABC
3 BCEF
4 ADG
5 BDEFH
6 CFI
7 DEGH
8 GHI
9 EFHI

输入9个整数,表示各时钟指针的起始位置,相邻两个整数之间用单个空格隔开。其中,0=12点、1=3点、2=6点、3=9点。输出输出一个最短的移动序列,使得9个时钟的指针都指向12点。按照移动的序号从小到大输出结果。相邻两个整数之间用单个空格隔开。样例输入

3 3 0
2 2 2
2 1 2

样例输出

4 5 8 9 

每个钟表有4种拨法,且与顺序无关,枚举即可 4^9种可能
#include <iostream>
#include <stdio.h>
#include <cstring>
using namespace std;
#define INF 0x3f3f3f3f;
int ori[][], s[][];
int t[]; bool ok()
{
for (int i = ; i <=; i++) {
for (int j = ; j <=; j++) {
if (s[i][j])
return ;
}
}
return ;
}
int main()
{
//freopen("1.txt", "r", stdin);
for (int i = ; i <= ; i++)
for (int j = ; j <= ; j++)
cin >> ori[i][j]; int Min = INF;
for (int i1 = ; i1 < ; i1++)
for (int i2 = ; i2 < ; i2++)
for (int i3 = ; i3 < ; i3++)
for (int i4 = ; i4 < ; i4++)
for (int i5 = ; i5 < ; i5++)
for (int i6 = ; i6 < ; i6++)
for (int i7 = ; i7 < ; i7++)
for (int i8 = ; i8 < ; i8++)
for (int i9 = ; i9 < ; i9++) {
memcpy(s, ori, sizeof(ori)); //每种枚举情况都是独立的
s[][] = (s[][]+i1+i2+i4)%; //A
s[][] = (s[][]+i1+i2+i3+i5)%;//B
s[][] = (s[][]+i2+i3+i6)%;//C
s[][] = (s[][]+i1+i4+i5+i7)%;//D
s[][] = (s[][]+i1+i3+i5+i7+i9)%;//E
s[][] = (s[][]+i3+i5+i6+i9)%;//F
s[][] = (s[][]+i4+i7+i8)%;//G
s[][] = (s[][]+i5+i7+i8+i9)%;//H
s[][] = (s[][]+i6+i8+i9)%;//I
if (ok()) {
int tot = i1+i2+i3+i4+i5+i6+i7+i8+i9;
// cout << tot << endl;
if (tot < Min) {
Min = tot;
t[] = i1; t[] = i2; t[] = i3;
t[] = i4; t[] = i5; t[] = i6;
t[] = i7; t[] = i8; t[] = i9;
}
} }
for (int i = ; i <= ; i++) {
if (t[i] && i!=) {
for (int j = ; j < t[i]; j++)
cout << i << " ";
}
else if (t[i] && i == ) {
for (int j = ; j < t[i]-; j++)
cout << i << " ";
cout << i;
}
} return ;
}
												

[poj]开关类问题 枚举 位运算的更多相关文章

  1. POJ 2436 二进制枚举+位运算

    题意:给出n头牛的得病的种类情况,一共有m种病,要求找出最多有K种病的牛的数目: 思路:二进制枚举(得病处为1,否则为0,比如得了2 1两种病,代号就是011(十进制就是3)),首先枚举出1的个数等于 ...

  2. 深入V8引擎-枚举+位运算实现参数配置

    不知不觉都快月底了,看了看上一篇还是6号写的,惭愧惭愧,说好的坚持.为了证明没有偷懒(其实还是沉迷了一会dota2),先上一个图自证清白. 基本上从初始化引擎,到Isolate.handleScope ...

  3. c#枚举位运算操作

    抛出预设问题 需要有一个npc需要在一周中的,周一,周二,周三会出现,其他时间不可见 解决问题 因为一周时间是固定的,所以创建枚举类型比较合适,如下 enum Days { None, Sunday, ...

  4. POJ 1166 The Clocks [BFS] [位运算]

    1.题意:有一组3*3的只有时针的挂钟阵列,每个时钟只有0,3,6,9三种状态:对时针阵列有9种操作,每种操作只对特点的几个时钟拨一次针,即将时针顺时针波动90度,现在试求从初试状态到阵列全部指向0的 ...

  5. poj 1222 EXTENDED LIGHTS OUT(位运算+枚举)

    http://poj.org/problem?id=1222 题意:给一个确定的5*6放入矩阵.每一个格子都有一个开关和一盏灯,0表示灯没亮,1表示灯亮着.让你输出一个5*6的矩阵ans[i][j], ...

  6. AcWing95. 费解的开关 枚举+位运算

    这道题的确比较难想,首先我们知道图比较小,有可能是枚举,那么该如何枚举呢??? 你可以发现,我们只要把第一排定了,并且保证第一排不准动,那么答案就定了 也就是说,我们首先用二进制枚举,枚举第一行需要翻 ...

  7. [POJ] 2453 An Easy Problem [位运算]

    An Easy Problem   Description As we known, data stored in the computers is in binary form. The probl ...

  8. BZOJ 1647 [Usaco2007 Open]Fliptile 翻格子游戏:部分枚举 位运算

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1647 题意: 在一个n*m(1 <= n,m <= 15)的棋盘上,每一个格子 ...

  9. POJ 1753 bfs+位运算

    T_T ++运算符和+1不一样.(i+1)%4 忘带小括号了.bfs函数是bool 型,忘记返回false时的情况了.噢....debug快哭了...... DESCRIPTION:求最少的步骤.使得 ...

随机推荐

  1. 解决win7打印机共享出现“无法保存打印机设置(错误0x000006d9)的问题

    最新解决win7打印机共享出现“无法保存打印机设置(错误0x000006d9)的问题,由系统下载吧率先分享: 有些用户在使用Windows7系统过程中,碰到到win7打印机共享出现“无法保存打印机设置 ...

  2. Linux入门基础(三)——系统命令

  3. Maximum Subsequence Sum 【DP】

    Given a sequence of K integers { N​1​​, N​2​​, -, N​K​​ }. A continuous subsequence is defined to be ...

  4. iOS开发的10个奇袭

    1.关于关键字volatile 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了.精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这 ...

  5. nodejs搭建简单的websocket服务端

    创建websocket服务端使用了nodejs-websocket ,首先要安装nodejs-websocket,在项目的目录下: npm install nodejs-websocket 1.搭建w ...

  6. 一、为什么要学习Java虚拟机?

    一.为什么要学习Java虚拟机?       这里我们使用举例来说明为什么要学习Java虚拟机,其实这个问题就和为什么要学习数据结构和算法是一个道理,工欲善其事,必先利其器.曾经的我经常害怕处理内存溢 ...

  7. React之jsx语法特性

    jsx 语法,直接可以在js中使用html标签. 还可以通过花括号的形式,在html标签中,写js表达式. <div> { 1 + 2 } hello,world! </div> ...

  8. 使用libcurl,根据url下载对应html页面

    1. [图片] Capture.JPG ​2. [代码]GetPageByURL //static member variable definestring GetPageByURL::m_curPa ...

  9. android程序的真正入口

    代码出自MtAndroid 3.1.2完全开发手册,适用于Android平台. 概述 android程序的真正入口是Application类的onCreate方法.它的继承关系如下所示: java.l ...

  10. c语言字符串 数字转换函数大全

    最近学数据结构老是做实验 常用到字符串和数字的转换 想找却发现网上的资料太散 所以搜集整理一下 方便以后再用 atof(将字符串转换成浮点型数) atoi(将字符串转换成整型数) atol(将字符串转 ...