DFS+BFS+MAP+剪枝

题意:

      就是给你一个10*10的连连看状态,然后问你最后能不能全部消没?

思路:

     首先要明确这是一个搜索题目,还有就是关键的一点就是连连看这个游戏是存在决策的,就是如果当前的这个点可以连接好几个点的话,我们选择那个点连接是不一样的,所以还要遍历所有的可能连接点,这样考虑的话单纯的一个搜索肯定不行了,可以用一个深搜套广搜的的结构,深搜是为了遍历顺序,广搜所为了得到当前点可以消去那些点(必要一个一个搜,要直接把所有的可能都搜出来,就是把杭电的那个bfs扩展下),但是直接暴力时间复杂度肯定接受不了,目测是,目测是多少我也不知道,但是存在这样的数据t = O(100^25),所以要优化,关键是在优化,下面是我能想到的几个优化

(1)首先把所有的卡片都单独拿出来,放到一个结构体里面,这样每次遍历的时候直接就只遍历数组,不用遍历所有的图。

(2)直接判断每种卡片出现的次数的奇偶。

(3)还有就是开一个状态记录当前的这个状态是否出现过,这个我是用的map进行hash的,这个优化有种记忆化搜索的感觉。

(4)还有最后一个(百度的),也是最关键的,如果有两种卡片都只剩下两个了,并且出现这样的姿势

AB

BA

   显然这样是连接不了的,这样感觉不会优化多少,但是在这个题目里,这样貌似优化很大,原因我感觉是在卡片的种类上的原因,卡片种类只有4种,这个也只是猜测,其实我力推的优化是(2,3)可惜没有4一直超时。

还有就是一定要明确,连连看是存在决策问题的。

#include<map>

#include<queue>

#include<stdio.h>

#include<string.h>

#include<string>

using namespace std;

typedef struct

{

    int x ,y ,t;

}NODE;

typedef struct

{

    int x ,y;

}CARD;

NODE xin ,tou;

CARD card[105];

CARD can[105];

int ss[5];

int cans ,mkans ,n ,m ,nowc ,cards;

int _map[12][12];

int dir[4][2] = {0 ,1 ,0 ,-1 ,1 ,0 ,-1 ,0};

map<string ,int>MARK;

bool ok(int x ,int y)

{

    return x >= 1 && x <= n && y >= 1 && y <= m && (!_map[x][y] || _map[x][y] == nowc);

}

bool jude()

{

    char str[105];

    for(int i = 1 ;i <= cards ;i ++)

    if(_map[card[i].x][card[i].y]) str[i-1] = 'a';

    else str[i-1] = 'b';

    str[cards] = '\0';

    if(MARK[str]) return 0;

    MARK[str] = 1;

    return 1;

}

int BFS(int x ,int y)

{

    int mark[12][12] = {0};

    nowc = _map[x][y];

    cans = 0;

    xin.x = x ,xin.y = y ,xin.t = 0;

    queue<NODE>q;

    q.push(xin);

    while(!q.empty())

    {

        tou = q.front();

        q.pop();

        if(_map[tou.x][tou.y] == nowc && !(tou.x == x && tou.y == y))

        {

            cans ++;

            can[cans].x = tou.x;

            can[cans].y = tou.y;

            continue;

        }

        if(tou.t >= 3) continue;

        for(int i = 0 ;i < 4 ;i ++)

        {

            xin.x = tou.x ,xin.y = tou.y ,xin.t = tou.t + 1;

            while(1)

            {

                xin.x += dir[i][0];

                xin.y += dir[i][1];

                if(!ok(xin.x ,xin.y)) break;

                if(!mark[xin.x][xin.y])

                {

                    mark[xin.x][xin.y] = 1;

                    q.push(xin);

                }

            }

        }

    }

    return cans;

}

bool CCC(int a ,int b)

{

    for(int i = 1 ;i <= cards ;i ++)

    {

        int x = card[i].x ,y = card[i].y;

        if(_map[x][y] == a)

        {

            if(_map[x+1][y+1] == a && _map[x+1][y] == b && _map[x][y+1] == b)

            return 1;

            return 0;

        }

        if(_map[x][y] == b)

        {

            if(_map[x+1][y+1] == b && _map[x+1][y] == a && _map[x][y+1] == a)

            return 1;

            return 0;

        }

    }

}

bool CUT()

{

    for(int i = 1 ;i <= 4 ;i ++)

    for(int j = i + 1 ;j <= 4 ;j ++)

    {

        if(ss[i] == ss[j] && ss[i] == 2)

        {

            if(CCC(i ,j)) return 1;

        }

    }

    return 0;

}

void DFS(int nows)

{

    if(!nows) mkans = 1;

    if(mkans) return ;

    if(!jude()) return ;

    if(CUT()) return ;

    for(int i = 1 ;i <= cards ;i ++)

    {

        if(mkans) return ;

        int x = card[i].x ,y = card[i].y;

        if(!_map[x][y]) continue;

        BFS(x ,y);

        ss[_map[x][y]] -= 2;

        for(int j = 1 ;j <= cans ;j ++)

        {

            int tmp = _map[x][y];

            int xx = can[j].x ,yy = can[j].y;

            _map[x][y] = _map[xx][yy] = 0;

            DFS(nows - 2);

            _map[x][y] = _map[xx][yy] = tmp;

        }

        ss[_map[x][y]] += 2;

    }

}

int main ()

{

    char str[12];

    while(~scanf("%d %d" ,&n ,&m) && n + m)

    {

        memset(_map ,0 ,sizeof(_map));

        memset(ss ,0 ,sizeof(ss));

        cards = 0;

        for(int i = 1 ;i <= n ;i ++)

        {

            scanf("%s" ,str);

            for(int j = 1 ;j <= m ;j ++)

            {

                if(str[j-1] == '*') _map[i][j] = 0;

                else

                {

                    _map[i][j] = str[j-1] - 'A' + 1;

                    cards ++;

                    card[cards].x = i;

                    card[cards].y = j;

                    ss[_map[i][j]] ++;

                }

            }

        }

        if(ss[1]%2 || ss[2]%2 || ss[3]%2 || ss[4]%2)

        {

            printf("no\n");

            continue;

        }

        mkans = 0;

        MARK.clear();

        DFS(cards);

        mkans ? printf("yes\n"):printf("no\n");

    }

    return 0;

}

POJ2308连连看dfs+bfs+优化的更多相关文章

  1. DFS/BFS+思维 HDOJ 5325 Crazy Bobo

    题目传送门 /* 题意:给一个树,节点上有权值,问最多能找出多少个点满足在树上是连通的并且按照权值排序后相邻的点 在树上的路径权值都小于这两个点 DFS/BFS+思维:按照权值的大小,从小的到大的连有 ...

  2. 【DFS/BFS】NYOJ-58-最少步数(迷宫最短路径问题)

    [题目链接:NYOJ-58] 经典的搜索问题,想必这题用广搜的会比较多,所以我首先使的也是广搜,但其实深搜同样也是可以的. 不考虑剪枝的话,两种方法实践消耗相同,但是深搜相比广搜内存低一点. 我想,因 ...

  3. ID(dfs+bfs)-hdu-4127-Flood-it!

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4127 题目意思: 给n*n的方格,每个格子有一种颜色(0~5),每次可以选择一种颜色,使得和左上角相 ...

  4. hdu 4109 dfs+剪枝优化

    求最久时间即在无环有向图里求最远路径 dfs+剪枝优化 从0节点(自己添加的)出发,0到1~n个节点之间的距离为1.mt[i]表示从0点到第i个节点眼下所得的最长路径 #include<iost ...

  5. [LeetCode] 130. Surrounded Regions_Medium tag: DFS/BFS

    Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'. A reg ...

  6. HDU 4771 (DFS+BFS)

    Problem Description Harry Potter has some precious. For example, his invisible robe, his wand and hi ...

  7. DFS/BFS视频讲解

    视频链接:https://www.bilibili.com/video/av12019553?share_medium=android&share_source=qq&bbid=XZ7 ...

  8. 2013年第四届蓝桥杯国赛 九宫重排(HashMap+双BFS优化)

    九宫重排     时间限制:1.0s   内存限制:256.0MB 问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干 ...

  9. POJ 3083 -- Children of the Candy Corn(DFS+BFS)TLE

    POJ 3083 -- Children of the Candy Corn(DFS+BFS) 题意: 给定一个迷宫,S是起点,E是终点,#是墙不可走,.可以走 1)先输出左转优先时,从S到E的步数 ...

随机推荐

  1. 怎样将大批量文件进行循环分组(reduce)?

    背景   当有时候一个文件夹下有几万个几十万个文件时,我们的桌面终端打开这个文件夹可能会卡.或者将文件进行批量上传时,如果是在文件夹下全选,那么基本上浏览器就卡死了,当然也不能这样子操作滴~   题主 ...

  2. Python 元类编程实现一个简单的 ORM

    概述 什么是ORM? ORM全称"Object Relational Mapping",即对象-关系映射,就是把关系数据库的一行映射为一个对象,也就是一个类对应一个表,这样,写代码 ...

  3. 腾讯云发布存储一体机TStor,打通全面上云“最后一公里”

    随着云计算.大数据.人工智能等技术的发展,各行各业加速数据化转型,数据容量以前所未有的速度增长,本地存储难以适应数据的指数式增长. 另一方面,公有云因其易扩展.低成本.安全稳定的特点,逐渐被企业广泛应 ...

  4. Sentinel熔断降级

    sentinel流量控制 Sentinel流量控制&服务熔断降级介绍 流量控制介绍 在这里我用景区的例子解释一下 一个旅游景点日接待游客数量为8K,8K以后的游客就无法买票进去景区. 对应编程 ...

  5. FreeBSD 12.2 发布

    FreeBSD 团队宣布 FreeBSD 12.2 正式发布,这是 FreeBSD 12 的第三个稳定版本. 本次更新的一些亮点: 引入了对无线网络堆栈的更新和各种驱动程序,以提供更好的 802.11 ...

  6. Spring中各种扩展原理及容器创建原理

    一.BeanFactoryPostProcessor BeanFactory的后置处理器:在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容:所有的bean定义已经保 ...

  7. 去哪找Java练手项目?

    经常有读者在微信上问我: 在学编程的过程中,看了不少书.视频课程,但是看完.听完之后感觉还是不会编程,想找一些项目来练手,但是不知道去哪儿找? 类似的问题,有不少读者问,估计是大部分人的困惑. 练手项 ...

  8. Azure Front Door(三)启用 Web Application Firewall (WAF) 保护Web 应用程序,拒绝恶意攻击

    一,引言 上一篇我们利用 Azure Front Door 为后端 VM 部署提供流量的负载均衡.因为是演示实例,也没有实际的后端实例代码,只有一个 "Index.html" 的静 ...

  9. Android Studio 有关 RecycleView 的使用

    •导入相关包 右击File->Project Structure: 搜索  com.android.support: 找到 recyclerview: 导入好后 Sync Now 同步一下,到这 ...

  10. vue 快速入门 系列 —— 侦测数据的变化 - [vue 源码分析]

    其他章节请看: vue 快速入门 系列 侦测数据的变化 - [vue 源码分析] 本文将 vue 中与数据侦测相关的源码摘了出来,配合上文(侦测数据的变化 - [基本实现]) 一起来分析一下 vue ...