判断含有 face
四个字符的 2*2 字符框的个数,判断方法不止一种。
n*m 的区域中,有 (n - 1) * (m - 1)
个 2*2 的字符框,遍历时应注意范围,不要越界。
4 次 if
#include <bits/stdc++.h>
using namespace std;
// 给你 n∗m 的二维网格,求 2∗2 的方格的个数,方框里面的字符可以构成 'face'
void solve()
{
int n, m;
cin >> n >> m;
char a[n][m];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> a[i][j];
int ans = 0;
for (int i = 0; i < n - 1; i++)
for (int j = 0; j < m - 1; j++)
{
if (a[i][j] != 'f' && a[i][j + 1] != 'f' && a[i + 1][j] != 'f' && a[i + 1][j + 1] != 'f')
continue;
if (a[i][j] != 'a' && a[i][j + 1] != 'a' && a[i + 1][j] != 'a' && a[i + 1][j + 1] != 'a')
continue;
if (a[i][j] != 'c' && a[i][j + 1] != 'c' && a[i + 1][j] != 'c' && a[i + 1][j + 1] != 'c')
continue;
if (a[i][j] != 'e' && a[i][j + 1] != 'e' && a[i + 1][j] != 'e' && a[i + 1][j + 1] != 'e')
continue;
ans++;
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(false);
int t;
// cin >> t;
t = 1;
while (t--)
solve();
return 0;
}
set 集合
学过 STL 的同学可以使用 set
集合来判断:
#include <bits/stdc++.h>
using namespace std;
// 给你 n∗m 的二维网格,求 2∗2 的方格的个数,方框里面的字符可以构成 'face'
void solve()
{
int n, m;
cin >> n >> m;
char a[n][m];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> a[i][j];
int ans = 0;
for (int i = 0; i < n - 1; i++)
for (int j = 0; j < m - 1; j++)
{
set<char> s = {a[i][j], a[i][j + 1], a[i + 1][j], a[i + 1][j + 1]};
if (s.count('f') && s.count('a') && s.count('c') && s.count('e'))
ans++;
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(false);
int t;
// cin >> t;
t = 1;
while (t--)
solve();
return 0;
}
其他判断方法
我们在同学们的代码中还看到了一些其他的判断方法,例如:
#include <bits/stdc++.h>
using namespace std;
// 给你 n∗m 的二维网格,求 2∗2 的方格的个数,方框里面的字符可以构成 'face'
void solve()
{
int n, m;
cin >> n >> m;
char a[n][m];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> a[i][j];
int ans = 0;
for (int i = 0; i < n - 1; i++)
for (int j = 0; j < m - 1; j++)
{
int cc = a[i][j] + a[i][j + 1] + a[i + 1][j] + a[i + 1][j + 1];
if (cc == 'f' + 'a' + 'c' + 'e')
ans++;
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(false);
int t;
// cin >> t;
t = 1;
while (t--)
solve();
return 0;
}
这个写法在牛客的评测系统中是可以通过的,但是这样的写法是错误的。
事实上我们可以轻松举出反例,例如 dbbg
这四个字符的 ASCII 码和也是和 face
相等的。
a-z
对应 ASCII 码为97-122
。
但这样启发我们想到了一种可能的比较简洁的写法:
#include <bits/stdc++.h>
using namespace std;
// 给你 n∗m 的二维网格,求 2∗2 的方格的个数,方框里面的字符可以构成 'face'
int f(char c)
{
return c * c + 17;
}
void solve()
{
int n, m;
cin >> n >> m;
char a[n][m];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> a[i][j];
int ans = 0;
for (int i = 0; i < n - 1; i++)
for (int j = 0; j < m - 1; j++)
{
int cc = f(a[i][j]) + f(a[i][j + 1]) + f(a[i + 1][j]) + f(a[i + 1][j + 1]);
if (cc == f('f') + f('a') + f('c') + f('e'))
ans++;
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(false);
int t;
// cin >> t;
t = 1;
while (t--)
solve();
return 0;
}
我们只需要找到一个函数 f
,使得 f('f') + f('a') + f('c') + f('e')
的值在所有可能的情况中都是唯一的即可。
这里利用了类似于哈希的思想,但上面代码中 f
函数的有效性还有待验证,并不一定真的唯一,只是我们举的一个例子。