acwing95.费解的开关

尝试这一题前可以先看:翻硬币

你玩过“拉灯”游戏吗?

2525 盏灯排成一个 5×55×5 的方形。

每一个灯都有一个开关,游戏者可以改变它的状态。

每一步,游戏者可以改变某一个灯的状态。

游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也要相应地改变其状态。

我们用数字 11 表示一盏开着的灯,用数字 00 表示关着的灯。

下面这种状态

10111
01101
10111
10000
11011

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

01111
11101
10111
10000
11011

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

01111
11001
11001
10100
11011

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

输入格式

第一行输入正整数 n,代表数据中共有 n 个待解决的游戏初始状态。

以下若干行数据分为 n 组,每组数据有 55 行,每行 55 个字符。

每组数据描述了一个游戏的初始状态。

各组数据间用一个空行分隔。

输出格式

一共输出 n 行数据,每行有一个小于等于 66 的整数,它表示对于输入数据中对应的游戏状态最少需要几步才能使所有灯变亮。

对于某一个游戏初始状态,若 66 步以内无法使所有灯变亮,则输出 −1−1。

数据范围

0

输入样例:
3
00111
01011
10001
11010
11100

11101
11101
11110
11111
11111

01111
11111
11111
11111
11111

输出样例:

3
2
-1
import java.io.*;

//第二行决定第一行,第三行第二行....第五行决定第四行,前四行确定后再看看第五行是否都是1
//也就是第一行确定了,能否全亮就确定了,关键就在于怎么按第一行,所以可以枚举第一行的所有可能性
public class Main
{
    
    static char[][] g = new char[5][5];
    static char[][] backup = new char[5][5];
    
    static int dx[] = {0,-1,0,1,0};
    static int dy[] = {0,0,1,0,-1};
    static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    
    public static void turn(int x, int y)
    {
        for(int i = 0; i < 5; i++)
        {
            int a = x + dx[i];
            int b = y + dy[i];
            if(a >= 0 && a < 5 && b >= 0 && b < 5)  g[a][b] ^= 1;
        }
    }
    
    public static void main(String[] args) throws IOException
    {
        int T = Integer.parseInt(in.readLine());
        while(T-- > 0)
        {
            int res = Integer.MAX_VALUE;
            
            for(int i = 0;i < 5; i++)
                g[i] = in.readLine().toCharArray();
            in.readLine();  
        
        
        
        for(int op = 0;op < 1<<5 ;op ++)
        {
            //因为需要多次操作g[][],所以可以每次都存一份它的备份
            
            for(int i = 0;i < 5;i++)
                backup[i] = g[i].clone();
            
            int step = 0;
            
            //确定第一行有哪些需要改变
            for(int i = 0; i < 5;i++)
            {
                if((op >> i & 1) == 0)
                {
                    step++;
                    turn(0,i);
                }
                    
                }
            
            //确定前四行
            for(int i = 0; i < 4;i++)
                for(int j = 0;j < 5;j++)
                    if(g[i][j] == '0')
                    {
                        step++;
                        turn(i+1,j);
                    }
            //再判断最后一行
            boolean flag = false;
            for(int i = 0;i < 5; i ++)
                if(g[4][i] == '0')
                {
                    flag = true;
                    break;
                }
            
            //如果flag没被改变        
            if(!flag) res = Math.min(res,step);
            
            for(int i = 0;i < 5;i ++)
                g[i] = backup[i].clone();
                
            }
        if(res > 6) res =  -1;
        System.out.println(res);
        }
        in.close();
    }
}

你可能感兴趣的:(算法,java,算法,数据结构)