问题描述

一个由按钮组成的矩阵,其中每行有6个按钮,共5行。每个按钮的位置上有一盏灯。当按下一个按钮后,该按钮以及周围位置(上边、下边、左边、右边)的灯都会改变一次。即,如果灯原来是点亮的,就会被熄灭;如果灯原来是熄灭的,则会被点亮。在矩阵角上的按钮改变3盏灯的状态;在矩阵边上的按钮改变4盏灯的状态;其他的按钮改变5盏灯的状态。

在上图中,左边矩阵中用X标记的按钮表示被按下,右边的矩阵表示灯状态的改变。对矩阵中的每盏灯设置一个初始状态。请你按按钮,直至每一盏等都熄灭。与一盏灯毗邻的多个按钮被按下时,一个操作会抵消另一次操作的结果。在下图中,第2行第3、5列的按钮都被按下,因此第2行、第4列的灯的状态就不改变。

请你写一个程序,确定需要按下哪些按钮,恰好使得所有的灯都熄灭。根据上面的规则,我们知道:

(1)第2次按下同一个按钮时,将抵消第1次按下时所产生的结果。因此,每个按钮最多只需要按下一次;

(2)各个按钮被按下的顺序对最终的结果没有影响;

(3)对第1行中每盏点亮的灯,按下第2行对应的按钮,就可以熄灭第1行的全部灯。如此重复下去,可以熄灭第1、2、3、4行的全部灯。同样,按下第1、2、3、4、5列的按钮,可以熄灭前5列的灯。

输入数据

第一行是一个正整数N,表示需要解决的案例数。每个案例由5行组成,每一行包括6个数字。这些数字以空格隔开,可以是0或1。0表示灯的初始状态是熄灭的,1表示灯的初始状态是点亮的。

输出要求

对每个案例,首先输出一行,输出字符串“PUZZLE #m”,其中m是该案例的序号。接着按照该案例的输入格式输出5行,其中的1表示需要把对应的按钮按下,0则表示不需要按对应的按钮。每个数字以一个空格隔开。

输入样例
2
0 1 1 0 1 0
1 0 0 1 1 1
0 0 1 0 0 1
1 0 0 1 0 1
0 1 1 1 0 0
0 0 1 0 1 0
1 0 1 0 1 1
0 0 1 0 1 1
1 0 1 1 0 0
0 1 0 1 0 0
输出样例
PUZZLE #1
1 0 1 0 0 1
1 1 0 1 0 1
0 0 1 0 1 1
1 0 0 1 0 0
0 1 0 0 0 0
PUZZLE #2
1 0 0 1 1 1
1 1 0 0 0 0
0 0 0 1 0 0
1 1 0 1 0 1
1 0 1 1 0 1

根据熄灯规则,如果矩阵press
是寻找的答案,那么按照press
的第一行对矩阵中的按钮操作之后,此时在矩阵的第一行上:
如果位置(1, j)上的灯是点亮的,则要按下位置(2, j)上按钮,即press[2][j]一定取1;
 如果位置(1, j)上的灯是熄灭的,则不能按位置(2, j)上按钮,即press[2][j]一定取0。
这样依据press
的第一、二行操作矩阵中的按钮,才能保证第一行的灯全部熄灭。而对矩阵中第三、四、五行的按钮无论进行什么样的操作,都不影响第一行各灯的状态。依此类推,可以确定press
第三、四、五行的值。
因此,一旦确定了press
第一行的值之后,为熄灭矩阵中第一至四行的灯,其他行的值也就随之确定了。press
的第一行共有2^6
种取值,分别对应唯一的一种press
取值,使得矩阵中前四行的灯都能熄灭。只要对这2^6
种情况进行判断就可以了:如果按照其中的某个press对矩阵中的按钮进行操作后,第五行的所有灯也恰好熄灭,则找到了答案。

解决方案

(1)对press
第一行的元素press[1][1]~ press [1][6]的各种取值情况进行枚举,依次考虑如下情况:

0 0 0 0 0 0

1 0 0 0 0 0

0 1 0 0 0 0

1 1 0 0 0 0

0 0 1 0 0 0

……

1 1 1 1 1 1

(2)
对press 第一行每一种取值,根据熄灯规则计算出press
的其他行的值。判断这个press
能否使得矩阵第五行的所有灯也恰好熄灭。

#include <stdio.h>
int puzzle[6][8],press[6][8]; bool guess()
{
int c,r;
for (r=1;r<5;r++ )
for (c=1;c<7;c++)
press[r+1][c]=(puzzle[r][c]+press[r][c]
+press[r-1][c]+press[r][c-1]
+press[r][c+1])%2;
for(c=1;c<7;c++) //判断最后一行是否熄灭
if ((press[5][c-1]+press[5][c]+press[5][c+1]
+press[4][c])%2!=puzzle[5][c])
return(false);
return true;
} int main(){
int cases,r,c;
unsigned i = 0 , j = 0;
unsigned int w = 1; for (r=0;r<6;r++)
press[r][0]=press[r][7]=0;
for (c=1;c<7;c++)
press[0][c]=0;
scanf("%d", &cases);
while(cases!=0){
for (r=1;r<6;r++)
for (c=1;c<7;c++)
scanf("%d", &puzzle[r][c]); //对第一行枚举64种操作
for(i = 0;i<64;i++){
w = 1;
for(j = 1;j < 7;j++){
press[1][7-j] = (i & w)>>(j-1);
//printf("%d ",w);
w = w << 1;
//printf("%d",press[1][7-j]);
}
//printf(" i=%d\n",i);
//000000 --- 11111111 press[1][1 ... 6]
//直到出现符合要求的
if(guess()){
break;
}
} printf("PUZZLE #%d\n",cases--);
for (r=1;r<6;r++)
{
for (c=1;c<7;c++)
printf("%d ",press[r][c]);
printf("\n");
}
}
return 0;
}

熄灯问题 --POJ 2811-ACM的更多相关文章

  1. POJ 3436 ACM Computer Factory (网络流,最大流)

    POJ 3436 ACM Computer Factory (网络流,最大流) Description As you know, all the computers used for ACM cont ...

  2. Poj 3436 ACM Computer Factory (最大流)

    题目链接: Poj 3436 ACM Computer Factory 题目描述: n个工厂,每个工厂能把电脑s态转化为d态,每个电脑有p个部件,问整个工厂系统在每个小时内最多能加工多少台电脑? 解题 ...

  3. OpenJudge 2811 熄灯问题 / Poj 1222 EXTENDED LIGHTS OUT

    1.链接地址: http://bailian.openjudge.cn/practice/2811 http://poj.org/problem?id=1222 2.题目: 总时间限制: 1000ms ...

  4. POJ 3464 ACM Computer Factory

    ACM Computer Factory Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4829 Accepted: 1641 ...

  5. POJ 3436 ACM Computer Factory

    题意:   为了追求ACM比赛的公平性,所有用作ACM比赛的电脑性能是一样的,而ACM董事会专门有一条生产线来生产这样的电脑,随着比赛规模的越来越大,生产线的生产能力不能满足需要,所以说ACM董事会想 ...

  6. POJ 3436 ACM Computer Factory 最大流,拆点 难度:1

    题目 http://poj.org/problem?id=3436 题意 有一条生产线,生产的产品共有p个(p<=10)零件,生产线上共有n台(n<=50)机器,每台机器可以每小时加工Qi ...

  7. POJ - 3436 ACM Computer Factory(最大流)

    https://vjudge.net/problem/POJ-3436 题目描述:  正如你所知道的,ACM 竞赛中所有竞赛队伍使用的计算机必须是相同的,以保证参赛者在公平的环境下竞争.这就是所有这些 ...

  8. POJ 3436 ACM Computer Factory(最大流+路径输出)

    http://poj.org/problem?id=3436 题意: 每台计算机包含P个部件,当所有这些部件都准备齐全后,计算机就组装完成了.计算机的生产过程通过N台不同的机器来完成,每台机器用它的性 ...

  9. POJ - 3436 ACM Computer Factory 网络流

    POJ-3436:http://poj.org/problem?id=3436 题意 组配计算机,每个机器的能力为x,只能处理一定条件的计算机,能输出特定的计算机配置.进去的要求有1,进来的计算机这个 ...

随机推荐

  1. 正则表达式的先行断言(lookahead)和后行断言(lookbehind)

    正则表达式的先行断言和后行断言一共有4种形式: (?=pattern) 零宽正向先行断言(zero-width positive lookahead assertion) (?!pattern) 零宽 ...

  2. [LeetCode] Palindrome Partitioning II 解题笔记

    Given a string s, partition s such that every substring of the partition is a palindrome. Return the ...

  3. Redis学习记录之Java中的初步使用

    1.关于Redis redis下载地址:<span style="font-family: Arial, Helvetica, sans-serif;">http:// ...

  4. xml学习篇(二) ----JSON 和XML对比

    在比较JSON和XML之前,我们先来上一堂关于数据格式的简要历史(更准确的说,是关于XML的始祖): 早在1970年,IBM开发了一种叫Generalized Markup Language的标记语言 ...

  5. gitlab 启动参考

    第一步 启动gitlab bundle exec rails s -e production -d 第二步 启动redis /etc/init.d/redis start chkconfig redi ...

  6. QT QObject::connect函数的学习

      从Qobject(QObject.h)源码中可以看到QObject::connect的定义是这样的: static bool connect(const QObject *sender, cons ...

  7. QTableWidget的使用和美工总结

    基本外观设置 FriendTable->setFrameShape(QFrame::NoFrame);  //设置边框 FriendTable->setHorizontalHeaderLa ...

  8. MapReduce分析明星微博数据

    互联网时代的到来,使得名人的形象变得更加鲜活,也拉近了明星和粉丝之间的距离.歌星.影星.体育明星.作家等名人通过互联网能够轻易实现和粉丝的互动,赚钱也变得前所未有的简单.同时,互联网的飞速发展本身也造 ...

  9. UITableView的简单应用介绍

    创建一个tableView视图,然后把这个视图界面添加到主界面上. _tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 20, [ ...

  10. PHP利用超级全局变量$_POST来接收表单数据。

    利用$_POST超级全局变量接收表单的数据,然后利用echo输出到页面. 下面是代码: <!doctype html> <html> <head> <titl ...