Luogu2040 | 打开所有的灯 (广搜+状压)

题目背景

pmshz在玩一个益(ruo)智(zhi)的小游戏,目的是打开九盏灯所有的灯,这样的游戏难倒了pmshz。。。

题目描述

这个灯很奇(fan)怪(ren),点一下就会将这个灯和其周围四盏灯的开关状态全部改变。现在你的任务就是就是告诉pmshz要全部打开这些灯。

例如:

0 1 1
1 0 0
1 0 1

点一下最中间的灯 \([2,2]\) 就变成了

0 0 1
0 1 1
1 1 1

再点一下左上角的灯 \([1,1]\) 就变成了

1 1 1
1 1 1
1 1 1

达成目标。最少需要 \(2\) 步。

输出 \(2\) 即可。

输入格式

九个数字,\(3*3\) 的格式输入,每两个数字中间只有一个空格,表示灯初始的开关状态。( \(0\) 表示关,\(1\) 表示开)

输出格式

一个整数,表示最少打开所有灯所需要的步数。

输入输出样例

输入 #1

0 1 1
1 0 0
1 0 1

输出 #1

2

——————————————————————————————————————
想了一会没有什么特别好的方法,所以直接搜索了,时间很充裕~

用二进制数表示九盏灯的开关状态,\(2^9 = 512\) 状态数允许完全被记录。

用 \(way\) 数组储存按下某栈灯时候会发生变化的灯的编号。

之后就是常规的广搜,\(vis\) 数组记录压缩后的每种状态实现需要的最少操作数。

代码如下:

#include <bits/stdc++.h>
#define MAX 666
using namespace std;
int init,vis[MAX];
int way[9][9]={{1,3,-1},{0,2,4,-1},{1,5,-1},
{0,4,6,-1},{1,3,5,7,-1},{2,4,8,-1},
{3,7,-1},{4,6,8,-1},{5,7,-1}};
queue<int> Q;
inline int read() {
    int X=0,w=0; char ch=0;
    while (!isdigit(ch)) w|=ch=='-',ch=getchar();
    while (isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
inline int open(int x,int opt) {
    int pos=0;
    while (way[opt][pos]!=-1) x^=(1<<way[opt][pos++]);
    return x^=(1<<opt);
}

int main() {
    memset(vis,-1,sizeof(vis));
    for (int i=1;i<=9;i++) init<<=1,init+=read();
    Q.push(init),vis[init]=0;
    while (!Q.empty()) {
        int now=Q.front(); Q.pop();
        for (int i=0;i<9;i++) {
            int tmp=open(now,i);
            if (vis[tmp]==-1) vis[tmp]=vis[now]+1,Q.push(tmp);
        }
    }
    printf("%d",vis[(1<<9)-1]);
    return 0;
} 

原文地址:https://www.cnblogs.com/zhwer/p/12294771.html

时间: 2024-08-13 22:28:53

Luogu2040 | 打开所有的灯 (广搜+状压)的相关文章

[noip模拟]食物中毒&lt;暴搜+状压优化&gt;

问题描述 Bqc经过一段时间的研究发现,要解这种毒需要一种特殊的药物.不幸的是,这种药物在 市面上不存在,没有办法Bqc只好亲自制得这种药物.它含有M种化学物质A1,A2,…,AM.现 在Bqc的手上有N种药材(每种药材只有一种),每种药材含有若干种化学物质(Bqc他有一种 机器,只要将药材放入机器,就能制得相应的药物). Bqc需要你的帮助,他希望你能帮他选取若干种药材,用这些选取的药材制作出Bqc需要 的药物.由于这些化学物质是有毒的,因此你选出来的药物,必须含有这M种化学物质. 有一点需要

HDU 4770 状压暴力枚举

Lights Against Dudely Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1415    Accepted Submission(s): 412 Problem Description Harry: "But Hagrid. How am I going to pay for all of this? I haven't

sicily 2011. Nine Digits(广搜,康托展开)

2011. Nine Digits Constraints Time Limit: 2 secs, Memory Limit: 256 MB Description Nine tiles, each with a number from 1 to 9 on it, are packed into a 3 by 3 frame. Your task is to arrange the tiles so that they are ordered as: 1 2 3 4 5 6 7 8 9 At e

NYOJ 284 坦克大战 &amp;&amp; POJ 2312 Battle City (广搜+优先队列)

链接:click here~~ 题意: 描述 Many of us had played the game "Battle city" in our childhood, and some people (like me) even often play it on computer now. What we are discussing is a simple edition of this game. Given a map that consists of empty space

Catch That Cow(广搜)

个人心得:其实有关搜素或者地图啥的都可以用广搜,但要注意标志物不然会变得很复杂,想这题,忘记了标志,结果内存超时: 将每个动作扔入队列,但要注意如何更简便,更节省时间,空间 Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and t

codevs 1225:八数码难题【双向广搜】

这里是传送门 这道题用普通BFS是可以做的,但是很明显没得过,效率太低了.效率更高的算法A*和双向广搜都可取,这写一下双向广搜的. 注意题目中的判重很重要,可以转化成九位数用hash来解决这个问题. #include <set> #include <string> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define

迷宫广搜

上学期学了C,这学期学C++.感觉最难的还是算法,上周作业的一道广搜题是我第一次接触广搜,由于第一学期刚学编程就接触的太多的算法难题,不禁对代码产生畏惧,不过还好没有放弃,虽然算法很难,但我慢慢找到了一点学数学时的乐趣.先介绍一下这道未来的我看过来会觉得很简单一道题吧 You are provided a maze(迷宫), and you need to program to find the least steps to walk from the start to the end.And

宽搜和广搜、

广搜与深搜的小区别 一般来说,广搜常用于找单一的最短路线,或者是规模小的路径搜索,它的特点是"搜到就是最优解", 而深搜用于找多个解或者是"步数已知(好比3步就必需达到前提)"的标题,它的空间效率高,然则找到的不必定是最优解,必需记实并完成全数搜索,故一般情况下,深搜需要很是高效的剪枝(优化). 像搜索最短路径这些的很显著若是用广搜,因为广搜的特征就是一层一层往下搜的,保证当前搜到的都是最优解,当然,最短路径只是一方面的操作,像什么起码状态转换也是可以操作的.深搜就

hdu1241详解 Java广搜搞定

import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { int m = sc.nextInt();//输入地图的行数 int n = sc.nextInt();//输入地图的列数 if (m == 0) {//若m=0则退出程序 break; } // 初始化图