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

    DFS函数大概率会传递"位置信息",根据位置信息获取下一步的选择,(大部分是在循环中)选择.执行.回退 例如N皇后的 棋盘位置(x, y),组合问题的 idx DFS函数的目的是, ...

  2. HDU 6386 Age of Moyu DFS+BFS

    /** HDU 6386 Age of Moyu DFS+BFS 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6386题意:1-->n的最小换乘次数 ...

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

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

  4. 链式前向星模板 建图+dfs+bfs+dijkstra

    边没有用struct封装起来,节点和边的计数起点如果不符合习惯可以稍作修改 建图+DFS+BFS #include <cstdio> #include <cstring> #i ...

  5. [Leetcode][第130题][JAVA][被围绕的区域][DFS][BFS]

    [问题描述][中等] [解答思路] 1. 深度优先搜索 使用深度优先搜索实现标记操作.在下面的代码中,我们把标记过的字母 O 修改为字母 A. 复杂度 class Solution {int[] dx ...

  6. 1.5万字详述 | 全开源:python写小游戏+AI强化学习与传统DFS/BFS控制分别实现

    简介:本周的强化学习我们来到实践部分.我以我在 GitHub 上开源的项目 PiperLiu / Amazing-Brick-DFS-and-DRL 为对象,从零开始与各位朋友分享:如何用 pytho ...

  7. java bfs dfs_java优先搜索(DFS/BFS)实际应用

    深度优先搜索DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.广度优先搜索BFS是Breadth First Sear ...

  8. E - Ricochet Robots( dfs+hash优化 )

    E - Ricochet Robots( dfs+hash优化 ) 题目链接:Gym - 100783E 题意: w*h的二维地图中,n个机器人,一个( 或者多个 )特定的点. 每次操作可以指定一个机 ...

  9. 魔板 Magic Squares(bfs优化)

    [USACO3.2]魔板 Magic Squares 题目背景 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 题 ...

最新文章

  1. 一行命令同时修改maven项目中多个mudule的版本号
  2. 在springboot项目中如何创建子项目
  3. [云炬创业管理笔记]第二章测试5
  4. python怎么调用列表_Python中列表的使用
  5. g开头的C语言编程软件,C语言函数大全(g开头)
  6. android 应用自动退出,android – 应用程序自动退出,没有任何警告或错误
  7. [13]2019-ICML-Active Learning for Probabilistic Structured Prediction of Cuts and Matchings
  8. tc275怎么移植到ram中去,把函数
  9. 【转】利用百度BAE3.0搭建原版WORDPRESS博客详细教程
  10. mysql repeated read_mysql事务之可重复读(Repeated Read)
  11. 解决USB无法识别问题
  12. 基于V4L2的视频驱动开发(1)
  13. 网站SEO诊断的六个方面
  14. Matlab 如何使用hold on与hold off
  15. 社会工程学之黑客七宗罪——傲慢(Hooking)
  16. 乐思蜀:我们不做网络民工
  17. freemarker自定义指令及方法
  18. VS 2005 SP1简体中文版下载地址
  19. Snort 预处理器 ——portscan
  20. SAP MRP设置默认值

热门文章

  1. 前端开发群技术文章分享汇总
  2. 【CentOS 7】关于php留言本网站的搭建
  3. PHP支付宝接口RSA验证
  4. 【转】使用Core Graphics绘画一个山寨微信icon
  5. python 线程指南
  6. 表达式解析执行器 IKExpression
  7. 尚学堂requireJs课程---2、模块
  8. SweetAlert2模态窗的使用
  9. feign date类型时间错误问题
  10. JSON API免费接口