搜索基础练习题

P2404 自然数的拆分问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

明目张胆的搜索题目,把每层搜索的值都相加,当等于目标值就收集输出结果。

每次搜索接着上一个数开始都从一开始会重复。

#include<bits/stdc++.h>
using namespace std;
int n,a[10]={0};
void dfs(int start,int sum,int t);
int main()
{
    scanf("%d",&n);
    dfs(1,0,1);
}
void dfs(int start,int sum,int t)
{
    int i;
    if(sum==n)
    {
        if(t-1==1)return;//防止输出7
        for(i=1;i<t;i++)
        {
            
            if(i==1)printf("%d",a[i]);
            else printf("+%d",a[i]);
        }
        cout<<endl;
        return;
    }
    for(i=start;i<=n;i++)
    {
        if(sum+i<=n)//过滤不必要的搜索
        {
            sum+=i;
            a[t++]=i;
            dfs(i,sum,t);
            sum-=i;
            t--;//回溯
        }
        
    }
}

vs题解的大佬缩行大法:

#include<iostream>
using namespace std;
int a[10],n;
int p(int t)//打印
{
    for(int j=1;j<=t-1;j++){cout<<a[j]<<"+";}
    cout<<a[t]<<endl;
}
int js(int s,int t)
{
    if(s==0){p(t-1);return 0;} 
    for(int k=1;k<=s;k++){if((a[t-1]<=k)&&(k<n)){a[t]=k,s=s-k;js(s,t+1);s=s+k;}}//深搜
}
int main()
{
    cin>>n;
    js(n,1);
}

P1294 高手去散步 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

将每一个地方都作为搜索的开始(因为高手有时光机)可以想象成一个图表(行列都是1到n)搜索,从左到右搜索可以去的地方,将去过的地方标记,再下一个地方从头到尾搜索即可。

#include<stdio.h>
int a[21][21],b[21];
int n,m,max;
void dfs(int i,int sum);

int main()
{
    scanf("%d %d",&n,&m);
    int i,j;
    for(i=0;i<m;i++)
    {
        int x,y,s;
        scanf("%d %d %d",&x,&y,&s);
        a[x][y]=a[y][x]=s;
    }
    for(i=1;i<=n;i++)//每个地方都作为开始
    {
        int sum=0;
        dfs(i,sum);
    }
    printf("%d",max);
}
void dfs(int i,int sum)
{
    int k;
    b[i]=1;//标记
    for(k=1;k<=n;k++)
    {
        if(a[i][k]&&b[k]==0)
        {
           sum+=a[i][k];//累加路程
           if(sum>max)max=sum;//更新最大值  
           dfs(k,sum);//进入下一个地方
           sum-=a[i][k];//回溯
        }
    }
    b[i]=0;//也是回溯
}

P1706 全排列问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

数学全排列,搜索(dfs)的入门模板,

#include<stdio.h>
int a[10],book[10];
int n;
void dfs(int step);

int main()
{
    scanf("%d",&n);
    dfs(1);//以每一步进入搜索
}
void dfs(int step){
    int k;
    if(step==n+1)//排完输出
    {
        for(k=1;k<=n;k++)
        {
            printf("%5d",a[k]);//要求输出格式很坑
            if(k%n==0)printf("\n");
        }
        
        return;
    }
    for(k=1;k<=n;k++)//寻找没排的数
    {
        if(book[k]==0)
        {
            book[k]=1;//标记
            a[step]=k;//排数
            dfs(step+1);//下一步
            book[k]=0;//回溯
        }
    }
    return;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值