判断含有 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 函数的有效性还有待验证,并不一定真的唯一,只是我们举的一个例子。