• 《算法问题实战策略》 BOGGLE


    oj地址是韩国网站 连接比较慢 https://algospot.com/judge/problem/read/BOGGLE
    大意如下

    输入输出

    输入
    1
    URLPM
    XPRET
    GIAET
    XTNZY
    XOQRS
    6
    PRETTY
    GIRL
    REPEAT
    KARA
    PANDORA
    GIAZAPX
    
    输出
    PRETTY YES
    GIRL YES
    REPEAT YES
    KARA NO
    PANDORA NO
    GIAZAPX YES

    估摸着很简单 就蹭蹭8个方向DFS 代码写完
    测试用例过了
    代码如下

    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    int n, m;
    int record = 0;
    const int dx[8] = { -1,-1,-1,1,1,1,0,0 };
    const int dy[8] = { -1,0,1,-1,0,1,-1,1 };
    
    bool isrange(int x, int y) {
        if (x < 0 || x >= 5 || y < 0 || y >= 5)
            return false;
    
        return true;
    }
    
    
    
    bool hasword(int x, int y, const string& word ,int idx,const vector<vector<char>>& table)
    {
        if (!isrange(x, y)) return false;
    
        if (table[x][y] != word[idx]) return false;
    
        if (idx == word.size()-1) return true;
    
        for (int i = 0; i < 8; i++) {
            int nextx = x + dx[i];
            int nexty = y + dy[i];
            if (hasword(nextx, nexty, word,idx+1, table))
                return true;
        }
    
        return false;
    }
    
    
    
    int main()
    {
        int t = 0;
        cin >> t;
        while (t--) {
            vector<vector<char>> table(5, vector<char>(5, 0));
            for (int i = 0; i < 5; i++) {
                for (int j = 0; j < 5; j++) {
                    cin >> table[i][j];
                }
            }
    
            int check = 0;
            cin >> check;
            vector<string> checkWord;
    
            while (check--) {
                string s;
                cin >> s;
                int find = 0;
                record = 0;
                for (int i = 0; i < 5; i++) {
                    for (int j = 0; j < 5; j++) {
                        if (hasword(i, j, s, 0,table)) {
                            cout << s << " YES" << endl;
                            find = 1;
                            goto LABEL;
                        }
                    }
                }
    
            LABEL:
                if (0 == find) {
                    cout << s << " NO" << endl;
                }
            }
        }
    
    
        return 0;
    }
    View Code

    但是居然一个特殊用例过不了 代码被判为TLE

    输入
    1
    AAAAA
    AAAAA
    AAAAA
    AACCC
    AACCB
    1
    AAAAAAAAAB

    左思右想不得其门 只得针对该例子进行了特殊处理 翻转字符串!
    添加代码不多 仅仅多了 reverse(s.begin(), s.end()); 一行

     1 #include <iostream>
     2 
     3 #include <iostream>
     4 #include <string>
     5 #include <vector>
     6 #include <algorithm>
     7 
     8 using namespace std;
     9 
    10 int n, m;
    11 
    12 const int dx[8] = { -1,-1,-1,1,1,1,0,0 };
    13 const int dy[8] = { -1,0,1,-1,0,1,-1,1 };
    14 
    15 vector<vector<int>> mem(5, vector<int>(5, 0));
    16 
    17 bool isrange(int x, int y) {
    18     if (x < 0 || x >= 5 || y < 0 || y >= 5)
    19         return false;
    20 
    21     return true;
    22 }
    23 
    24 
    25 
    26 bool hasword(int x, int y, const string& word, int idx, const vector<vector<char>>& table)
    27 {
    28     if (!isrange(x, y)) {
    29         return false;
    30     }
    31 
    32     if (table[x][y] != word[idx]) {
    33 
    34         return false;
    35     }
    36 
    37     if (idx >= word.size() - 1) return true;
    38 
    39     for (int i = 0; i < 8; i++) {
    40         int nextx = x + dx[i];
    41         int nexty = y + dy[i];
    42         if (hasword(nextx, nexty, word, idx + 1, table))
    43             return true;
    44     }
    45 
    46     return false;
    47 }
    48 
    49 
    50 
    51 int main()
    52 {
    53     int t = 0;
    54     cin >> t;
    55     while (t--) {
    56         vector<vector<char>> table(5, vector<char>(5, 0));
    57         for (int i = 0; i < 5; i++) {
    58             for (int j = 0; j < 5; j++) {
    59                 cin >> table[i][j];
    60             }
    61         }
    62 
    63         int check = 0;
    64         cin >> check;
    65         vector<string> checkWord;
    66 
    67         while (check--) {
    68             string s;
    69             cin >> s;
    70             string copys = s;
    71             reverse(s.begin(), s.end());
    72             int find = 0;
    73             for (int i = 0; i < 5; i++) {
    74                 for (int j = 0; j < 5; j++) {
    75                     mem[i][j] = 1;
    76                 }
    77             }
    78             for (int i = 0; i < 5; i++) {
    79                 for (int j = 0; j < 5; j++) {
    80                     if (hasword(i, j, s, 0, table)) {
    81                         cout << copys << " YES" << endl;
    82                         find = 1;
    83                         goto LABEL;
    84                     }
    85                 }
    86             }
    87 
    88         LABEL:
    89             if (0 == find) {
    90                 cout << copys << " NO" << endl;
    91             }
    92         }
    93     }
    94 
    95 
    96     return 0;
    97 }
    View Code

    但是实际上 当测试字符串为AAAAAAAAABAAAAAAAA 也一样会TLE
    所以 实际上我们需要使用数组缓存从当前格子出发不能解决的字符串记录 避免多次重复尝试失败的路径
    代码添加了一个变量数组
    int d[x][y][l]; 记录x y格子出发的尝试匹配长度为l的字符串 能否成功,如果失败则置0。
    下次DFS 发现该标记为 0 则直接返回 不进行尝试

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int T,n,c[15][15],cw[15],len[15];
     4 char a[15][15],w[15][15];
     5 int nx[10] = {1,0,-1,-1,-1,0,1,1},ny[10] = {1,1,1,0,-1,-1,-1,0};
     6 int dx,dy,is;
     7 int d[15][15][15];
     8 
     9 int dfs(int x,int y,int now,int l)
    10 {
    11     if(d[x][y][l]) return 0;
    12     if(l == len[now]) return 1;
    13     d[x][y][l] = 1;
    14     is = 0;
    15     for(int i = 0;i < 8;i++)
    16     {
    17         dx = x+nx[i];
    18         dy = y+ny[i];
    19         if(a[dx][dy] == w[now][l])
    20         {
    21             if(dfs(dx,dy,now,l+1))
    22             {
    23                 //c[x][y] = 0;
    24                 return 1;
    25             }
    26         }
    27     }
    28     //d[x][y][l] = 0;
    29     return 0;
    30 }
    31 
    32 int main()
    33 {
    34     scanf("%d",&T);
    35     while(T--)
    36     {
    37         memset(cw,0,sizeof(cw));
    38         for(int i = 1;i <= 5;i++)
    39         {
    40             for(int j = 1;j <= 5;j++)
    41             {
    42                 scanf(" %c",&a[i][j]);
    43             }
    44         }
    45         scanf("%d",&n);
    46         for(int i = 1;i <= n;i++)
    47         {
    48             scanf("%s",w[i]);
    49             len[i] = strlen(w[i]);
    50             for(int j = 1;j <= 5;j++)
    51             {
    52                 for(int k = 1;k <= 5;k++)
    53                 {
    54                     if(a[j][k] == w[i][0])
    55                     {
    56                         if(dfs(j,k,i,1))
    57                         {
    58                             cw[i] = 1;
    59                             break;
    60                         }
    61                     }
    62                 }
    63                 if(cw[i]) break;
    64             }
    65             memset(d,0,sizeof(d));
    66         }
    67         for(int i = 1;i <= n;i++)
    68         {
    69             printf("%s %s
    ",w[i],((cw[i] == 1) ? "YES" : "NO"));
    70         }
    71     }
    72 }
    View Code
    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    线程的等待与唤醒
    多线程start()与run()的区别
    Thread与Runnable
    关于i++和++i的一些见解
    Mysql优化(转)
    Java 注解
    Java 泛型(转)
    Java 中的CAS
    CAS ABA问题
    Java 线程池分析
  • 原文地址:https://www.cnblogs.com/itdef/p/11524930.html
Copyright © 2020-2023  润新知