P9303 [CCC 2023 J5] CCC Word Hunt
思路
看到题目后我立马想到了搜索方法中的洪水填充。
首先输入后先遍历一遍所有的字符,看与字符串的第一个字符是否相同,若相同则可以以这个点为起点开始搜索。每次若出格或不与想要的字符相同则立马返回,若字符一一对应则让结果加一。
因为可以在中途转
附代码:
#include <bits/stdc++.h>
using namespace std;
int dx[8] = {0, -1, -1, -1, 0, 1, 1, 1}, dy[8] = {-1, -1, 0, 1, 1, 1, 0, -1}, r, c, ans = 0;
//dx[8],dy[8]分别是向8个方向分别移动后的行列变化,ans是总数
char a[105][105];
string s;
void srh(int x, int y, int now, int t, bool k)//分别是横坐标,纵坐标,进行到字符串的第几个字符,搜索方向和当前是否转过弯
{
if(x <= 0 || x > r || y <= 0 || y > c || a[x][y] != s[now])
return ;//字符出格或与s中的字符不匹配时退出
if(now == s.length() - 1)
{
ans++;
return ;
}//与字符串匹配,答案数加一
srh(x + dx[t], y + dy[t], now + 1, t, k);
if(k && now != 0)
{
srh(x, y, now, (t + 6) % 8, false);
srh(x, y, now, (t + 2) % 8, false);
}//若拐弯了立即将k设为false
}
int main()
{
cin >> s;
cin >> r >> c;
for(register int i = 1; i <= r; i++)
for(register int j = 1; j <= c; j++)
cin >> a[i][j];
for(register int i = 1; i <= r; i++)
for(register int j = 1; j <= c; j++)
if(a[i][j] == s[0])
for(register int k = 0; k < 8; k++)
srh(i, j, 0, k, true);//若与字符串第零个字符相同,则从此点开始搜索
cout << ans << endl;
return 0;
}