码迷,mamicode.com
首页 > 编程语言 > 详细

《算法问题实战策略》 BOGGLE

时间:2019-09-16 00:09:18      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:cto   show   for   print   algo   方向   goto   避免   返回   

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

标签:cto   show   for   print   algo   方向   goto   避免   返回   

原文地址:https://www.cnblogs.com/itdef/p/11524930.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!