Day 2 搜索
1. P1019 单词接龙
字符串搜索。DFS * 1
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
2. P1101 单词方阵
DFS * 2
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
3. P1332 血色先锋队
需注意感染源为多个,需要在搜索前入队。BFS * 1
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
4. P1331 海战
特判是否有船只接触 + BFS求连通块即可(输入字符数组时,请使用cin,否则会粗大问题~)。BFS * 2
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
5. P3956 棋盘
利用记忆化搜索的方法,将每次经过一个点的总花费存下来,之后不断维护最小值,若一次经过该点的花费>该点的花费最小值,则剪枝。DFS * 3
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
By ZRQ