第二次总结

自然数的拆分问题

 题目描述

任何一个大于 $1$ 的自然数 $n$,总可以拆分成若干个小于 $n$ 的自然数之和。现在给你一个自然数 $n$,要求你求出 $n$ 的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。然后你需要输出这些序列,其中字典序小的序列需要优先输出。

 输入格式

输入:待拆分的自然数 n。

 输出格式

输出:若干数的加法式子。

 样例 1

样例输入

7

 样例输出 #1

1+1+1+1+1+1+1

1+1+1+1+1+2

1+1+1+1+3

1+1+1+2+2

1+1+1+4

1+1+2+3

1+1+5

1+2+2+2

1+2+4

1+3+3

1+6

2+2+3

2+5

3+4

```

 提示

数据保证 1<=n<=8。

思路:这个题使用DPS就可以解决,假设我们输入7,数组内有 1 1 1 1 1 1 1 ,然后最后一个1变为2,从2~6去试,看看此时的sum等不等于7,要是为7,我们就打印数组得到结果,要是不都等于7(也就是大于),就回到 1 1 1 1 1 1 (6),也就是6个1的状态,再让最后一个1从2~6去试,要是sum都不等于7,就回到 1 1 1 1 1(6) (6),也就是5个1的状态,依次递归,来得到不同结果下的答案

#include<bits/stdc++.h>

using namespace std;

int arr[200],n;

void print(int cnt)

{

printf("%d",arr[0]);

for(int i=1;i<cnt;i++)

printf("+%d",arr[i]);

printf("\n");

}

void dps(int pos,int cnt,int sum)

{

if(sum>n)

return ;

else if(sum==n)

{

print(cnt);

}

else

{

for(int i=pos;i<n;i++)

{

arr[cnt]=i;

dps(i,cnt+1,sum+i);

}

}

}

int main()

{

scanf("%d",&n);

dps(1,0,0);

return 0;

 }

题目描述
给定一个 N×M 方格的迷宫,迷宫里有 T 处障碍,障碍处不可通过。

在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍

给定起点坐标和终点坐标,每个方格最多经过一次,问有多少种从起点坐标到终点坐标的方案

输入格式
第一行为三个正整数 N,M,TN,M,T,分别表示迷宫的长宽和障碍总数

第二行为四个正整数 SX,SY,FX,FY  SX,SY 代表起点坐标,FX,FY 代表终点坐标。

接下来 T 行,每行两个正整数,表示障碍点的坐标。

输出格式 
输出从起点坐标到终点坐标的方案总数
输入输出样
输入
2 2 1
1 1 2 2
1 2
输出
1

思路:也是一样的用DPS就可以解决,我们先将迷宫中可以走的赋值为1,不可以(或走过的)走的赋值为0,首先将起点坐标给传入dps,然后对坐标的上下左右四个发现进行判断,如果周围不为0,我们先将这个坐标设为0(因为走过了),然后将这个坐标递归传入dps中,再进行判断,但是要注意:如果不满足递归条件后跳出的坐标,我们要重新赋值为1(相当于没走这个坐标),然后判断它的周围的其他坐标,然后如果遇到了结束坐标,我们就++,最后得到答案

#include<bits/stdc++.h>
using namespace std;
int arr[15][15]={0},n,m,ans=0,t,x,y,sx,sy,fx,fy;
int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
void dfs(int x,int y)
{
    if(x==fx&&y==fy)
    {
    ans++;    
    return ;    
    }
    else
    {
        for(int i=0;i<4;i++)
        {
            if(arr[x+dx[i]][y+dy[i]]!=0)
            {
                arr[x+dx[i]][y+dy[i]]=0;
                dfs(x+dx[i],y+dy[i]);
                arr[x+dx[i]][y+dy[i]]=1;
            }
            
        }
    }
}
int main()
{
    cin>>n>>m>>t;
    cin>>sx>>sy>>fx>>fy;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    arr[i][j]=1;
    arr[sx][sy]=0; 
    for(int i=0;i<t;i++)
    {
        cin>>x>>y;
        arr[x][y]=0;
    }
    dfs(sx,sy);
    cout<<ans;
    return 0;
 } 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值