《算法问题实战策略》 BOGGLE

Posted itdef

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《算法问题实战策略》 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\\n",w[i],((cw[i] == 1) ? "YES" : "NO"));
70         
71     
72 
View Code

 

以上是关于《算法问题实战策略》 BOGGLE的主要内容,如果未能解决你的问题,请参考以下文章

Coursera 算法二 week 4 Boggle

《算法问题实战策略》-chaper7-穷举法

算法问题实战策略 QUADTREE

算法问题实战策略 FENCE

算法问题实战策略 DICTIONARY

算法问题实战策略 MEETINGROOm