Day 2 搜索

1. P1019 单词接龙

字符串搜索。DFS * 1

 1 #include <iostream>
 2 using namespace std;
 3 const int MAXN = 25;
 4 int n, ans, vis[MAXN], cvr[MAXN][MAXN];
 5 char ch;
 6 string ins[MAXN];
 7 int max(int a, int b)
 8 {
 9     if(a >= b) return a;
10     return b;
11 }
12 int cal(int a, int b)
13 {
14     bool f = false;
15     for(int i = ins[a].size() - 1; i >= 0; --i)
16     {
17         for(int na = i, nb = 0; na <= ins[a].size() - 1; ++na, ++nb)
18             if(ins[a][na] != ins[b][nb])
19             {
20                 f = true;
21                 break;
22             }
23         if(f == false)
24             return ins[a].size() - i;
25         f = false;
26     }
27     return 0;
28 } 
29 void DFS(int len, int l)
30 {
31     bool f = false;
32     for(int i = 1; i <= n; ++i)
33     {
34         if(cvr[l][i] != 0 && vis[i] < 2 && cvr[l][i] != ins[l].size() && cvr[l][i] != ins[i].size())
35         {
36             f = true;
37             ++vis[i];
38             DFS(len + ins[i].size() - cvr[l][i], i);
39             --vis[i];
40         }
41         if(f == false)
42             ans = max(len, ans);
43     }
44     return ;
45 }
46 int main()
47 {
48     cin >> n;
49     for(int i = 1; i <= n; ++i)
50         cin >> ins[i];
51     cin >> ch;
52     for(int i = 1; i <= n; ++i)
53         for(int j = 1; j <= n; ++j)
54             cvr[i][j] = cal(i, j);
55     for(int i = 1; i <= n; ++i)
56         if(ins[i][0] == ch)
57         {
58             ++vis[i];
59             DFS(ins[i].size(), i);
60             --vis[i];
61         }
62     cout << ans << endl;
63     return 0;
64 } 
View Code

2. P1101 单词方阵

DFS * 2

 1 #include <iostream>
 2 #include <queue>
 3 using namespace std;
 4 const int MAXN = 110;
 5 int n, d[8][2] = {1, 0, -1, 0, 0, 1, 0, -1, 1, 1, 1, -1, -1, 1, -1, -1}, st[10][2];
 6 char map[MAXN][MAXN], s[8];
 7 bool vis[MAXN][MAXN];
 8 void DFS(int count, int x, int y, int f)
 9 {
10     if(count == 8)
11     {
12         for(int i = 1; i <= 7; ++i)
13             vis[st[i][0]][st[i][1]] = true;//标记为一个完整的单词 
14         return ;
15     }
16     int nx = x + d[f][0], ny = y + d[f][1];
17     if(map[nx][ny] == s[count] && nx >= 1 && nx <= n && ny >= 1 && ny <= n)
18     {
19         st[count][0] = nx;
20         st[count][1] = ny;
21         DFS(count + 1, nx, ny, f);
22     }
23     return ;
24 }
25 int main()
26 {
27     s[1] = 'y';
28     s[2] = 'i';
29     s[3] = 'z';
30     s[4] = 'h';
31     s[5] = 'o';
32     s[6] = 'n';
33     s[7] = 'g';
34     cin >> n;
35     for(int i = 1; i <= n; ++i)
36         for(int j = 1; j <= n; ++j)
37             cin >> map[i][j];
38     for(int i = 1; i <= n; ++i)
39         for(int j = 1; j <= n; ++j)
40             if(map[i][j] == 'y')
41             {
42                 st[1][0] = i;//第1个点 
43                 st[1][1] = j;
44                 for(int k = 0; k <= 7; ++k)//8个方向 
45                     DFS(2, i, j, k);//从第2个点开始查 
46             }
47     for(int i = 1; i <= n; ++i)
48     {
49         for(int j = 1; j <= n; ++j)
50         {
51             if(vis[i][j] == true)
52                 cout << map[i][j];
53             else
54                 cout << '*';
55         }
56         cout << endl;
57     }
58     return 0;
59 }
View Code

3. P1332 血色先锋队

需注意感染源为多个,需要在搜索前入队。BFS * 1

 1 #include <cstdio>
 2 #include <queue>
 3 using namespace std;
 4 const int MAXN = 510, MAXM = 510, MAXA = 100100, MAXB = 100100;
 5 struct point
 6 {
 7     int x;
 8     int y;
 9     int t;
10 };
11 int n, m, a, b, map[MAXN][MAXM], d[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
12 bool vis[MAXN][MAXM];
13 point l[MAXB], s, e;
14 queue<point> Q;
15 void BFS(int n, int m)
16 {
17     while(!Q.empty())
18     {
19         s = Q.front();
20         Q.pop();
21         for(int i = 0 ; i <= 3; ++i)
22         {
23             e.x = s.x + d[i][0];
24             e.y = s.y + d[i][1];
25             e.t = s.t + 1;
26             if(vis[e.x][e.y] == false && e.x >= 1 && e.x <= n && e.y >= 1 && e.y <= n)
27             {
28                 vis[e.x][e.y] = true;
29                 map[e.x][e.y] = e.t;
30                 Q.push(e);
31             }
32         }
33     }
34     return ;
35 }
36 int main()
37 {
38     scanf("%d%d%d%d", &n, &m, &a, &b);
39     for(int i = 1; i <= a; ++i)
40     {
41         point p;
42         scanf("%d%d", &p.x, &p.y);
43         p.t = 0;
44         vis[p.x][p.y] = true;
45         map[p.x][p.y] = 0;
46         Q.push(p);
47     }
48     for(int i = 1; i <= b; ++i)
49         scanf("%d%d", &l[i].x, &l[i].y);
50     BFS(n, m);
51     for(int i = 1; i <= b; ++i)
52         printf("%d\n", map[l[i].x][l[i].y]);
53     return 0;
54 } 
View Code

4. P1331 海战

特判是否有船只接触 + BFS求连通块即可(输入字符数组时,请使用cin,否则会粗大问题~)。BFS * 2

 1 #include <iostream>
 2 #include <queue>
 3 using namespace std;
 4 const int MAXR = 1010, MAXC = 1010;
 5 struct point
 6 {
 7     int x;
 8     int y;
 9 };
10 int r, c, d[4][2] = {1, 0, -1, 0, 0, 1, 0, -1}, ans;
11 char map[MAXR][MAXC];
12 bool judge(int i, int j)//判断2*2的图形内是否有船只接触 
13 {
14     int c = 0;
15     if(map[i][j] == '#') ++c;
16     if(map[i + 1][j] == '#') ++c;
17     if(map[i][j + 1] == '#') ++c;
18     if(map[i + 1][j + 1] == '#') ++c;
19     if(c == 3) return true;
20     return false;
21 }
22 void BFS(int r, int c, int sx, int sy)//BFS求连通块 
23 {
24     point s, e;
25     queue<point> Q;
26     s.x = sx;
27     s.y = sy;
28     map[s.x][s.y] = '.';
29     Q.push(s);
30     while(!Q.empty())
31     {
32         s = Q.front();
33         Q.pop();
34         for(int i = 0; i <= 3; ++i)
35         {
36             e.x = s.x + d[i][0];
37             e.y = s.y + d[i][1];
38             if(map[e.x][e.y] == '#' && e.x >= 1 && e.x <= r && e.y >= 1 && e.y <= c)
39             {
40                 map[e.x][e.y] = '.';
41                 Q.push(e);
42             }
43         }
44     }
45     return ;
46 }
47 int main()
48 {
49     cin >> r >> c;
50     for(int i = 1; i <= r; ++i)
51         for(int j = 1; j <= c; ++j)
52             cin >> map[i][j];
53     for(int i = 1; i <= r - 1; ++i)
54         for(int j = 1; j <= c - 1; ++j)
55             if(judge(i, j) == true)//有相互接触的船只 
56             {
57                 cout << "Bad placement." << endl;
58                 return 0;
59             }
60     for(int i = 1; i <= r; ++i)
61         for(int j = 1; j <= c; ++j)
62             if(map[i][j] == '#')
63             {
64                 ++ans;
65                 BFS(r, c, i, j);
66             }
67     cout << "There are " << ans << " ships."<< endl;
68     return 0;
69 }
View Code

5. P3956 棋盘

利用记忆化搜索的方法,将每次经过一个点的总花费存下来,之后不断维护最小值,若一次经过该点的花费>该点的花费最小值,则剪枝。DFS * 3

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 const int MAXN = 1010, INF = 0x7f;
 5 int n, m, map[MAXN][MAXN], ans = 1e9, d[4][2] = {1, 0, -1, 0, 0, 1, 0, -1}, f[MAXN][MAXN];
 6 bool vis[MAXN][MAXN];
 7 void DFS(int x, int y, int c, int nc)
 8 {
 9     if(c >= f[x][y]) return ;
10     f[x][y] = c;
11     if(x == n && y == n)
12     {
13         ans = c;
14         return ;
15     } 
16     for(int i = 0; i <= 3; ++i)
17     {
18         int nx = x + d[i][0], ny = y + d[i][1];
19         if(vis[nx][ny] == false && nx >= 1 && nx <= n && ny >= 1 && ny <= n)
20         {
21             vis[nx][ny] = true;
22             if(map[x][y] != 0 && map[x][y] == map[nx][ny]) DFS(nx, ny, c, map[nx][ny]);//两格都有色且相等,花费为0 
23             else if(map[x][y] != 0 && map[nx][ny] != 0 && map[x][y] != map[nx][ny]) DFS(nx, ny, c + 1, map[nx][ny]);//两格都有色但不相等,花费为1 
24             else if(map[x][y] != 0 && map[nx][ny] == 0) DFS(nx, ny, c + 2, map[x][y]);//起点有色,终点无色,花费为2 
25             else if(map[x][y] == 0 && map[nx][ny] == nc) DFS(nx, ny, c, map[nx][ny]);//起点无色,终点有色,施法后颜色与终点颜色相同,花费为0 
26             else if(map[x][y] == 0 && map[nx][ny] != 0 && map[nx][ny] != nc) DFS(nx, ny, c + 1, map[nx][ny]);//起点无色,终点有色,施法后颜色与终点颜色相同,花费为1 
27             vis[nx][ny] = false;
28         }
29     }
30     return ;
31 }
32 int main()
33 {
34     memset(f, INF, sizeof(f));
35     scanf("%d%d", &n, &m);
36     for(int i = 1; i <= m; ++i)
37     {
38         int x, y, c;
39         scanf("%d%d%d", &x, &y, &c);
40         map[x][y] = c + 1;
41     }
42     DFS(1, 1, 0, map[1][1]);
43     if(ans == 1e9) printf("-1\n");
44     else printf("%d\n", ans);
45     return 0;
46 }
View Code

 

 

 

 

By ZRQ

posted @ 2020-03-03 13:51  ZRQ666  阅读(157)  评论(0编辑  收藏  举报