洛谷P1790 矩形分割

题目描述
有一个长为a,宽为b的矩形(1≤a≤6,2≤b≤6)。可以把这个矩形看作是a*b个小方格。

我们现在接到了这样的一个任务:请你计算出,把这个矩形分割成两个部分的方法总数。

你不是可以任意地分割这个大的矩形, 必须满足:

分割后,每个部分,至少各自均有一个方格是在大矩形的最外边上(即大矩形最外面一环的方格)。
在这里插入图片描述

输入输出格式
输入格式:
输入文件仅包含两个数字,a和b。

输出格式:
输出仅有1行,这一行仅有一个整数,表示分割的方案总数。

输入输出样例
输入样例#1:
3 2
输出样例#1:
15

看到这题,我十分的束手无策,但是当我认真看完题目之后,发现了

(1<=a,b<=6)

这就为暴力提供了很好的机会

我们可以把这个矩阵想象成一个无向图,然后就是求从一个边界点 出发(不走边界点)到另外一个边界点的方案数

但是这样可能行不通,因为你很难判断这个方案是否走过,我一开始想用状态压缩来判断这种方案是否出现过,后来发现没有这个必要

我们只需要从矩阵一条长和一条宽上的每个点出发,求出到另外一个边界点的方案数,记得不要从矩阵的端点出发

#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e1;
int n,m;
int ans=0;
int dx[4]={-1,0,1,0};//上下左右四个方向 
int dy[4]={0,1,0,-1};
bool map[N][N];//map判断这个点有没有走过 
void dfs(int x,int y)
{
    map[x][y]=1;//把这个点设置为走过 
    if(x==1||y==m||x==n||y==1){//如果到了边界点 
        ans++;
        map[x][y]=0;
        return;
    }
    for(int i=0;i<4;++i){//往四个方向搜索 
        int xx=x+dx[i],yy=y+dy[i];
        if(xx<1||yy<1||xx>n||yy>m||map[xx][yy])continue;
        dfs(xx,yy);
    }
    map[x][y]=0;//回溯 
}
int main()  {
    scanf("%d%d",&n,&m);
    n++;m++;//要多加一个点 
    memset(map,0,sizeof(map));//初始化所有的点都是可以走的 
    for(int i=2;i<n;++i){
        map[i][1]=1;//把这个点设置为不能走 
        dfs(i,2);//直接从下一个点开始搜索,保证不会走边界 
        map[i][1]=0;//回溯 
    }
    for(int i=2;i<m;++i){//同上 
        map[1][i]=1;
        dfs(2,i);
        map[1][i]=0;
    }
    printf("%d\n",ans);//输出 
    return 0;
}

好了,文章就到这里了

其实,我一开始想这个代码的时候发现了一个似乎存在的bug

那就是我从//(x,y)表示(行,列)
(1,2)->(2,2)->(2,1)

(2,1)->(2,2)->(1,2)
不是一样的吗,为什么这样可行?
这个问题让你们自己去想!!!









































提示:
只从两条边开始搜索

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值