hdu 2209 状态压缩广搜

思路:    20张牌     有1>>20中情况        用二进制标记,  这道题的关键地方就是怎样无翻牌     这里用到位运算   1^x    若x为0  则为1   否则为0  这里正好用到翻牌     对前两张和后两张  都可以和3(11)进行异或运算     对中间的和7(111) 进行异或运算

#include<stdio.h>
#include<queue>
#include<string.h>
#include<iostream>
using namespace std;

int mark[1<<20],leap[20],num[20],step[1<<20],n;
int bfs()
{
    int a=0,b,t=1;
    for(int i=n-1;i>=0;i--)
    {
        a+=num[i]*t;
        t*=2;
    }
    memset(mark,0,sizeof(mark));
    memset(step,-1,sizeof(leap));
    mark[a]=1;
    step[a]=0;
    queue<int>q;
    q.push(a);
    while(!q.empty())
    {
        b=q.front();
        q.pop();
        if(b==0) return 0;
        for(int i=0;i<n;i++)
        {
            a=b^leap[i];
            if(!mark[a])
            {
                mark[a]=1;
                step[a]=step[b]+1;
                q.push(a);
            }
        }
    }
    return 0;
}
int main()
{
    char str[30];
    int i,j;
    while(~scanf("%s",str))
    {
        n=strlen(str);
        for(i=0;i<n;i++)
        num[i]=str[i]-‘0‘;
        leap[0]=3;
        leap[n-1]=(3<<(n-2));
        for(i=1;i<n-1;i++)
        leap[i]=(7<<(i-1));
        bfs();
        if(step[0]==-1) printf("NO\n");
        else printf("%d\n",step[0]);
    }
    return 0;
}
时间: 2024-10-03 22:54:24

hdu 2209 状态压缩广搜的相关文章

POJ 1753 Flip game状态压缩+广搜

题意有4*4的16个方格,每个方格有黑白两种颜色,每次点击方格后,被点击方格本身及其上下左右的方格都会改变颜色.给出一组状态,求将这组状态变为全白或者全黑至少需要点击几次.若无法达到,则输出Impossible. 样例输入bwwbbbwbbwwbbwww 样例输出4 思路每个方格只有黑白两种颜色,且只有16个方格,因此可以把每个状态看作一个16位的二进制数(状态压缩),2^16=25536,因此可以用int来保存状态.然后就是BFS暴搜,直到状态为0或者65535(全1)为止. 注意点65535

HDU 1253 (简单三维广搜) 胜利大逃亡

奇葩!这么简单的广搜居然爆内存了,而且一直爆,一直爆,Orz 而且我也优化过了的啊,尼玛还是一直爆! 先把代码贴上睡觉去了,明天再来弄 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <queue> 6 #include <cmath> 7 using namespace std; 8 9 struct Poin

HDU 1240 (简单三维广搜) Asteroids!

给出一个三维的迷宫以及起点和终点,求能否到大终点,若果能输出最短步数 三维的问题无非就是变成了6个搜索方向 最后强调一下xyz的顺序,从输入数据来看,读入的顺序是map[z][x][y] 总之,这是很基础的一道题 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <queue> 6 #include <algorithm

POJ 2411 Mondriaan&#39;s Dream(状态压缩+深搜)

每一行的填充仅与上一行有关系,每行的目的都是至少填充满上一行. 当填充到i行的时候,i-1行某列没填充必须用竖直的方格填充,这是固定的,剩下其余的则搜索填充. 用2进制的01表示不放还是放 第i行只和i-1行有关 枚举i-1行的每个状态,推出由此状态能达到的i行状态 如果i-1行的出发状态某处未放,必然要在i行放一个竖的方块,所以我对上一行状态按位取反之后的状态就是放置了竖方块的状态. 然后用搜索扫一道在i行放横着的方块的所有可能,并且把这些状态累加上i-1的出发状态的方法数,如果该方法数为0,

hdu 5180 状态压缩 dp 打表

hdu 5180 状态压缩 dp 打表 题意: 在n*n的国际象棋中,放置若干个国王和k个车,使得国王之间不互相攻击,车之间不互相攻击,车不可攻击到国王(这并不代表国王不能攻击到车).国王能攻击到它上下左右,左上左下右上右下八个位置的棋子,车可以攻击到同一行或同一列中的棋子,求方案总数对1000000007取模后的值. 限制: 1 <= n <=15; 0 <= k <=15 思路: 状态压缩,dp,打表套打表 打表程序如下: 打表程序1: tab[a][b]表示a*b的棋盘王的放

hdu 4917Permutation(状态压缩DP)

hdu 4917Permutation(状态压缩DP) 题意:将1~n的n个数排列成序列(n<=40),但有m(m<=20)个限制条件,其中第i个限制条件的表示为ai,bi.表示该序列的第ai的数要小于第bi的.问有多少中排列?保证有解 解法:我们首先可以明确一点,这m个限制条件,所表示的关系会构成若干个DAG(有向无环图,我将其称之为拓扑图).我们只要将这n个数,填入到拓扑图上,使其满足拓扑关系,那么这样的序列就是可以的.而这若干个拓扑图之间,是不会相互影响的,因而我们可以单独考虑每一个拓扑

hdu 3811 状态压缩

题意就不对说了:  开始想用深搜过  感觉数据水的话应该能过,  哈哈  还是超时了!!! 正确做法应该是状态压缩吧,n小于等于17    2^17-1种状态,每种状态表示对应的数用没用过,如果用状态压缩dp的思路(从小状态跑到大状态)的话就不对了,开始一直没想明白,仔细想想也是,如果按以前的 就会改变dp里面的值,实际上对每一种状态的值是一定的,还有就是为什么要跑结果的对立面,看看测试数据   ,两个要求之间是有重复的,比如1,1和2,2    这样跑起来就不方便. 跑的时候三重for   外

HDU 4101 有意思的广搜

题意:在一个n*n的矩阵内,两个人想要找到一个 " 宝藏 ",用-1表示.其中有空地,每回合可任意穿梭,用0表示,有怪物,无法直接穿过,需要杀死,每回合砍1 HP,等于0时死亡,由两人从最外围开始,每人一回合行动,问谁能获得 "  宝藏  " . 题解: 看似博弈 ,同样可以从必胜状态考虑,当宝藏周围只剩下最后一圈血量为1的怪物时,  谁先打死那个怪物,谁就输了. 两人都不愿意杀死那只堵着宝藏门的第一只怪 ,所以两人的状态就是一直在砍门外面的怪,你一刀我一刀.所以我

[HDU]5094Maze(状态压缩BFS)

状态压缩的题,第一次WA了,怎么改都不对,交了十几遍,之后重新写了一个,1A了 #include<cstdio> #include<queue> #include<cstring> #include<algorithm> using namespace std; const int maxn = 51; const int dir[4][2] = {{0,1},{-1,0},{0,-1},{1,0}}; int n,m,t; int door[maxn][m