zoukankan      html  css  js  c++  java
  • HDU 1501 Zipper(Dfs记忆化搜索)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1501

    题意:前两个字符串能和能合成第三个字符串,字符串内相对顺序不变

    开始用Dfs()以为用了变量标记如果失败不停的return。。。。然后超时,然后想不通为什么要用vis[i][j]来标记有没访问过该状态,我当时想Dfs(i,j,k)里面都一直在递增啊,而且如果失败了回溯的时候就return了,怎么还会遇到该状态呢。。。。。。原来如果在递归的第一个Dfs()匹配成功,回溯后(i,j,k就隐式地减少了),而且遇到flag也不会return(因为flag是失败才return的),然后进了第二个Dfs()。。。。如果没有vis[i][j]的话,就会在里面浪费时间了。。。。。。。所以vis[i][j]是不管你成功还是失败,只要以前有过这个状态就会return

    先发错误代码:

    #include <iostream>
    using namespace std;
    
    const int M = 555;
    
    char c1[M], c2[M], c3[M];
    int l1, l2, l3;
    int flag;
    
    bool Dfs(int i, int j, int k)
    {
        if (flag == 0)
        {
            return 0;
        }
        
        if (c1[i] != c3[k] && c2[j] != c3[k])
        {
            flag = 0;//这里也是错的,这个条件不一定就匹配不了。。。因为还有剩余的没搜
            return 0;//这题我们应该是在所有的情况里找到能匹配的话就标记flag = 1,即求是否存在可以匹配的情况
        }
    
        if (k == l3)
        {
            return 1;
        }
        
        if (c1[i] == c3[k] && i + 1 < l1)
        {
            Dfs(i + 1, j, k + 1);
            if (flag == 0)//匹配成功在这里就不会return,再进下面的Dfs()就会有重复的状态了
            {
                return 0;
            }
        }
        
        if (c2[j] == c3[k] && j + 1 < l2)
        {
            Dfs(i, j + 1, k  + 1);
            if (flag == 0)
            {
                return 0;
            }
        }
        if (flag)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
    
    
    int main()
    {
        int t;
        scanf("%d", &t);
        int case1 = 0;
        while (t--)
        {
            scanf("%s%s%s", c1, c2, c3);
            l1 = strlen(c1);
            l2 = strlen(c2);
            l3 = strlen(c3);
            flag = 1;
            
            if (l1 + l2 != l3)
            {
                flag = 0;
            }
            printf("Date set %d: %s\n", ++case1, Dfs(0, 0, 0) ? "yes" : "no");
        }
        return 0;
    }

    AC代码:

    #include <iostream>
    using namespace std;
    
    const int M = 555;
    
    char c1[M], c2[M], c3[M];
    int l1, l2, l3;
    int flag;
    bool vis[M][M];
    
    void Dfs(int i, int j, int k)
    {
        
        if (vis[i][j])
        {
            return ;
        }
        
        vis[i][j] = 1;
        
        if (k == l3)
        {
            flag = 1;
            return ;
        }
        
        if (c1[i] != c3[k] && c2[j] != c3[k])
        {
            return ;
        }
        
        
        
        if (c1[i] == c3[k] && i + 1 <= l1)
        {
            Dfs(i + 1, j, k + 1);
            
        }
        
        if (c2[j] == c3[k] && j + 1 <= l2)
        {
            Dfs(i, j + 1, k  + 1);
        }
        
    }
    
    
    int main()
    {
        int t;
        scanf("%d", &t);
        int case1 = 0;
        while (t--)
        {
            scanf("%s%s%s", c1, c2, c3);
            l1 = strlen(c1);
            l2 = strlen(c2);
            l3 = strlen(c3);
            flag = 0;
            
            if (l1 + l2 != l3)
            {
                flag = 0;
                printf("Data set %d: %s\n", ++case1, flag ? "yes" : "no");
                continue;
            }
            memset(vis, 0, sizeof(vis));
            Dfs(0, 0, 0);
            printf("Data set %d: %s\n", ++case1, flag ? "yes" : "no");
        }
        return 0;
    }
  • 相关阅读:
    ubuntu安装sublime无工具栏解决办法
    ubuntu安装eclipse无工具栏解决办法
    数据库设计
    cglib代理
    多线程简单实例(3)线程池
    多线程简单实例(2)生产者和消费者
    STL之迭代器(iterator)
    STL之vector
    “由于这台计算机没有终端服务器客户端访问许可证”解决方案
    STL之容器(containers) 简介
  • 原文地址:https://www.cnblogs.com/qiufeihai/p/2664438.html
Copyright © 2011-2022 走看看