zoukankan      html  css  js  c++  java
  • Hdu 1181 变形课

    Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1181

    看完这题首先想到的是用DFS,因为只要找到就行了,不求找到的最快方法。首先从开头字母为'b'的单词出发,目标为首尾相接,且末字母为'm'的单词。中间的搜索时的下一个链接单位自然是首尾相接的单词。

    DFS:

    #include <iostream>
    #include <cstring>
    #include <string>
    #include <cstdio>
    
    using namespace std;
    
    const int maxn = 1000 + 24;
    string word[maxn];
    bool vis[maxn];
    int pos;
    int flag=0;
    
    void dfs( string str )
    {
        if( flag )
            return ;
        int i;
        for( i=0;i<=pos;i++ )
            if( !vis[i] )
            {
                if( word[i][0] == str[ str.length()-1 ] && word[i][ word[i].length()-1 ]=='m' ) //满足首尾相连又已'm'结尾
                    flag=1;
                else if( word[i][0]==str[ str.length()-1 ] ) //满足首尾相连的情况
                {
                    vis[i]=true;
                    dfs( word[i] );
                    vis[i]=false;
                }
            }
    }
    
    int main()
    {
        pos=0;
        int i,j;
        memset( vis,false,sizeof(vis) );
        while( cin>>word[pos] )
        {
            if( word[pos][0]=='0' )   //以输入'0'为结尾
            {
                flag=0;
                for( i=0;i<=pos;i++ )
                {
                    if( word[i][0]=='b' )
                    {
                        vis[i]=true;
                        dfs( word[i] );
                        vis[i]=false;
                    }
                }
                if( flag )
                    cout<<"Yes.
    ";
                else
                    cout<<"No.
    ";
                pos=0;
                memset( vis,false,sizeof(vis) );  //重新初始化
            }
            else
                pos++; //没有结尾就一直输入下一个
        }
        return 0;
    }
    

    但当我AC后,稍微一思考,发现可以优化。因为我不需要关注你输入的单词的每一个字母,我所要知道的仅仅为每个输入单词的首字母与末字母。那么我可以建一个链接矩阵,表示两个字母间的链接关系。当然这个连接是单向的,比如输入big,'b'可以指向'g',而不是'g'指向'b'。

    此处用了BFS:

    #include <iostream>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <cstdio>
    
    using namespace std;
    
    const int maxn = 30;
    bool word[maxn][maxn]; //链接矩阵
    bool vis[maxn][maxn];  //是否已访问
    
    bool bfs()
    {
        const int start = 'b'-'a';
        const int finish = 'm'-'a';
        queue <int> qt;
        qt.push( start ); //从'b'出发
        int t, i;
        while( !qt.empty() )
        {
            t = qt.front();
            qt.pop();
    
            if( word[t][finish] )  //找到末尾是'm'的单词
                return true;
    
            for( i=0;i<='z'-'a';i++ )
                if( !vis[t][i] && word[t][i] )  //寻找未访问的首尾组合
                {
                    vis[t][i] = true;
                    qt.push(i);
                }
        }
        return false;
    }
    
    int main()
    {
        string temp;
        memset( vis, false, sizeof(vis) );
        memset( word, false, sizeof(word) );
        while( cin>>temp )
        {
            if( temp[0]=='0' )  //一组输入完毕
            {
                if( bfs() )
                    cout<<"Yes.
    ";
                else
                    cout<<"No.
    ";
                memset( vis, false, sizeof(vis) );
                memset( word, false, sizeof(word) );
            }
            else
                word[ temp[0]-'a' ][ temp[ temp.length()-1 ]-'a' ] = true;
    
        }
        return 0;
    }
    

    除了BFS,DFS,还可以用最短路径,判断起点'b'能否到'm'即可,这里就不贴代码了。网上也还有很多的其他解法。

    总之,这道题不难,但对扩展思路还是有一定帮助的。

  • 相关阅读:
    怎样编写YARN应用程序
    Oracle整形转字符串to_char()
    js 前加分号和感叹号的含义
    Android 多屏适配解决方式
    nginx负载均衡基于ip_hash的session粘帖
    mysql锁SELECT FOR UPDATE【转】
    redis主从复制
    mysql 优化实例之索引创建
    mysql sql优化实例
    MySQL 慢查询日志分析及可视化结果
  • 原文地址:https://www.cnblogs.com/Emerald/p/3984808.html
Copyright © 2011-2022 走看看