• 费解的开关


    题目描述

    你玩过“拉灯”游戏吗?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”。 

    样例输入

    3
    00111
    01011
    10001
    11010
    11100
    
    11101
    11101
    11110
    11111
    11111
    
    01111
    11111
    11111
    11111
    11111
    

    样例输出

    3
    2
    -1 
    反向BFS 用了位运算
    总共有0到(1<<25)-1 状态
    map来看这个状态有没有出现过
    #include <bits/stdc++.h>
    using namespace std;
    map<int,int>mp;
    int get_map(int x,int i)
    {
       x=x^(1<<i);
       if(i%5<4){//->
        x=x^(1<<(i+1));
       }
       if(i%5){//<-
        x=x^(1<<(i-1));
       }
       if(i>=5){//up
        x=x^(1<<(i-5));
       }
       if(i<20){//down
        x=x^(1<<(i+5));
       }
       return x;
    }
    void bfs()
    {
        queue<int>q;
        q.push((1<<25)-1);
        mp[(1<<25)-1]=1;
        while(!q.empty())
        {
            int now=q.front();
            q.pop();
            if(mp[now]==7) return;
            for(int i=0;i<25;i++){
               int net=get_map(now,i);
               if(mp[net]==0){
                mp[net]=mp[now]+1;
                q.push(net);
               }
            }
        }
    }
    int main()
    {
        int n;
        ios::sync_with_stdio(false);
        cin>>n;
        mp.clear();
        bfs();
        while(n--)
        {
            int sum=0;
            char a;
            for(int i=0;i<25;i++){
                cin>>a;
                if(a=='1') sum+=(1<<i);
            }
            cout<<mp[sum]-1<<endl;
        }
        return 0;
    }
    View Code

    不要忘记努力,不要辜负自己 欢迎指正 QQ:1468580561
  • 相关阅读:
    [Android6.0][RK3399] 双屏异显代码实现流程分析(二)【转】
    uboot中添加自己的命令【转】
    android压力测试命令monkey详解【转】
    T-sql语句修改数据库逻辑名、数据库名、物理名(sql2000)
    sql查询与修改数据库逻辑文件名,移动数据库存储路径
    如何修改SQL Server 2000的数据库逻辑与物理名称
    你是否也忘了刷新视图?
    单点登录CAS-Demo
    SQL Case when 的使用方法 (转)
    因为数据库正在使用,所以无法获得对数据库的独占访问权(转)
  • 原文地址:https://www.cnblogs.com/smallocean/p/9276003.html
Copyright © 2020-2023  润新知