洛谷P1790

这道题可以说也是非常有意思的数学题,并且坑点也是非常多
刚开始以为是连通块的问题,后面发现没有那么简单,因为必须要分成两个部分才行,连通块可能会分成三个部分
后面想到利用割痕来解决,以为唯一的一种分割方法都会对应一种割痕,所以把所有的顶点都抽象出来
最后问题可以转化为一个01矩阵的问题
坑点有回溯,考虑两个点不能在一条边界上的情况,遇到不能走的点要及时跳出等等

敲着敲着突然发现键盘坏了,就是连续按d和a结果他会自动按f,有点小麻
当然不得不说这个题思维还是可以,可以看作01矩阵的升级版

#include <iostream>
#include <utility>
using namespace std;
typedef long long ll;
#define fi(i, a, b) for (int i = a; i <= b; ++i)
#define fr(i, a, b) for (int i = a; i >= b; --i)
#define x first
#define y second
#define sz(x) ((int)(x).size())
#define pb push_back
using pii = pair<int, int>;
//#define DEBUG
int n, m;
bool vis[10][10];
bool v[10][10];
int ans;
int matrix[10][10];
bool check(int x, int y)
{
    if (x == 1 || x == n + 1 || y == 1 || y == m + 1)
    {
        if (!matrix[x][y])
            return true;
        else
            return false;
    }
    else
        return false;
}
void dfs(int x, int y)
{
    if (v[x][y] || matrix[x][y])
        return;
        v[x][y] = true;
    if (!vis[x][y] && check(x, y))
    {
        v[x][y] = false;
        ans++;
        return;
    }
    if (x <= n && y != 1 && y != m + 1)
        dfs(x + 1, y);
    if (y <= m && x != 1 && x != n + 1)
        dfs(x, y + 1);
    if (y - 1 >= 1 && x != 1 && x != n + 1)
        dfs(x, y - 1);
    if (x - 1 >= 1 && y != 1 && y != m + 1)
        dfs(x - 1, y);
     v[x][y] = false;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> m;
    matrix[1][1] = matrix[1][m + 1] = matrix[n + 1][1] = matrix[n + 1][m + 1] = 1;
    fi(i, 1, n + 1) fi(j, 1, m + 1)
    {
        if (check(i, j))
        {
            fi(i,1,n+1) fi(j,1,m+1) v[i][j] = false;
            vis[i][j] = true;
            dfs(i, j);
        }
    }
    cout << ans << endl;
#ifdef DEBUG
    //freopen(D:\in.txt,r,stdin);
#endif
    return 0;
}
posted @ 2022-02-02 17:10  Sun-Wind  阅读(43)  评论(0编辑  收藏  举报