zoukankan      html  css  js  c++  java
  • tyvj1266 费解的开关

    描述

        你玩过“拉灯”游戏吗?25盏灯排成一个5x5的方形。每一个灯都有一个开关,游戏者可以改变它的状态。每一步,游戏者可以改变某一个灯的状态。游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也要相应地改变其状态。
        我们用数字“1”表示一盏开着的灯,用数字“0”表示关着的灯。下面这种状态

    10111
    01101
    10111
    10000
    11011

        在改变了最左上角的灯的状态后将变成:

    01111
    11101
    10111
    10000
    11011

        再改变它正中间的灯后状态将变成:

    01111
    11001
    11001
    10100
    11011

        给定一些游戏的初始状态,编写程序判断游戏者是否可能在6步以内使所有的灯都变亮。

    输入格式

        第一行有一个正整数n,代表数据中共有n个待解决的游戏初始状态。
        以下若干行数据分为n组,每组数据有5行,每行5个字符。每组数据描述了一个游戏的初始状态。各组数据间用一个空行分隔。
        对于30%的数据,n<=5;
        对于100%的数据,n<=500。

    输出格式

        输出数据一共有n行,每行有一个小于等于6的整数,它表示对于输入数据中对应的游戏状态最少需要几步才能使所有灯变亮。
        对于某一个游戏初始状态,若6步以内无法使所有灯变亮,请输出“-1”。

    测试样例1

    输入


    00111 
    01011 
    10001 
    11010 
    11100 

    11101 
    11101 
    11110 
    11111 
    11111 

    01111 
    11111 
    11111 
    11111 
    11111

    输出



    -1
    思路:
    枚举第一行的按灯方案,剩下的行需要刚好灭掉上一行没有灭掉的灯,最后再判断最后一行是否灯全部灭完
    代码:
    #include<cstring> 
    #include<cstdlib> 
    #include<cstdio> 
    #include<iostream> 
    using namespace std; 
    
    typedef int array[6]; 
    array a,b[6],c[6]; 
    int n,ans; 
    void Init() 
    { 
    char str[6]; 
    for (int i=1;i<=5;i++) 
    { 
    scanf("%s",str); 
    for (int j=1;j<=5;j++) 
    b[i][j]=str[j-1]-'0'; 
    } 
    } 
    int work() 
    { 
    int dep=0; 
    for (int i=1;i<=5;i++) 
    if (a[i]==1) 
    { 
    dep++; 
    c[1][i]^=1; c[2][i]^=1; 
    if (i>1) c[1][i-1]^=1; 
    if (i<5) c[1][i+1]^=1; 
    } 
    for (int i=2;i<=5;i++) 
    for (int j=1;j<=5;j++) 
    if (c[i-1][j]==0 && dep<=6) 
    { 
    dep++; 
    c[i][j]^=1; c[i-1][j]^=1; 
    if (j>1) c[i][j-1]^=1; 
    if (j<5) c[i][j+1]^=1; 
    if (i<5) c[i+1][j]^=1; 
    } 
    if (dep>=7) return 7; 
    for (int i=1;i<=5;i++) 
    if (c[5][i]==0) return 7; 
    return dep; 
    } 
    void solve() 
    { 
    Init(); 
    ans=0xFFFFFFF; 
    for (int a1=0;a1<=1;a1++) 
    for (int a2=0;a2<=1;a2++) 
    for (int a3=0;a3<=1;a3++) 
    for (int a4=0;a4<=1;a4++) 
    for (int a5=0;a5<=1;a5++) 
    { 
    memcpy(c,b,sizeof(c)); 
    a[1]=a1; a[2]=a2; a[3]=a3; a[4]=a4; a[5]=a5; 
    int step=work(); 
    if (step<ans) ans=step; 
    if (ans==2) 
    { 
    printf("2
    "); 
    return ; 
    } 
    } 
    if (ans<=6) printf("%d
    ",ans); 
    else printf("-1
    "); 
    } 
    int main() 
    { 
    scanf("%d",&n); 
    for (int test=1;test<=n;test++) solve(); 
    return 0; 
    }
  • 相关阅读:
    MSCRM 2011 自定义页面 CrmService 实现增,删,改,查需要注意的
    Microsoft Dynamics CRM 4.0,IFD验证下,自定义aspx页面,如何获取当前的用户ID ?
    CRM 4.0表单脚本开发一览
    MSCRM关于时区时间的操作
    常用JS操作方法
    详解 Visual C# 数据库编程
    Java 日志
    《信息检索导论》第二十章总结
    java文件添加包语句后的编译和运行问题
    查看端口占用情况:FPort和Moo0 ConnectionWatcher软件介绍
  • 原文地址:https://www.cnblogs.com/hyfer/p/5812575.html
Copyright © 2011-2022 走看看