搜索总结

本文介绍了多种基于搜索的算法在不同问题中的应用,包括售货员的烦恼、装箱问题、素数路、运输方案、泡泡龙游戏、字母游戏、单词接龙、神秘数列、和为零的数列构造等。通过对具体问题的分析和解决方案,展示了搜索算法在解决实际问题时的灵活性和实用性。
摘要由CSDN通过智能技术生成
组合数输出
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
typedef long long ll;

int n,m;
vector<int> v;

void slove(int x)
{
   
    if(v.size()==m)///组合数满了,输出
    {
   
        int flag=0;
        for(int i=0;i<m;i++)  printf("%3d",v[i]);
        printf("\n");
        return;
    }
    if(x>n) return ;///超出边界,返回
    for(int i=x;i<=n;i++)
    {
   
        v.push_back(i);///选择数i,然后进入下一层搜索
        slove(i+1);
        v.pop_back();///回溯,在递归回去的时候将这个数还原为原来未访问的状态,不选择这个数,进入循环的下一个数
    }
}

int main()
{
   
    cin>>n>>m;
    slove(1);
}

问题 H: 【搜索】售货员的烦恼(trouble)

题目:
一间冰淇淋商店刚刚开张,外面有2×N个人购买1元的冰淇淋,其中一半人拿着1张2元人民币,另一半人拿一张1元人民币。售货员很粗心,没有准备零钱,要使出售过程中不发生找钱困难的问题,这2×N个人应该如何排队?请你帮售货员找出所有方案数量的总和。
输入
一个整数N(N≤15)。
输出
方案总数M。
代码+注释

#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
typedef long long ll;
int ans=0,n;
int tot1=0,tot2=0;
void slove(int index)
{
   
    if(tot1>n||tot2>n||tot2>tot1||index>2*n) return;///不符合条件,剪枝
    else if(index==2*n) {
   ans++;return;}///达到终点,ans++
    else
    {
   
        tot1++;///放1
        slove(index+1);///向下一层搜索
        tot1--,tot2++;///不放1,放2
        slove(index+1);///向下一层搜索
        tot2--; return;///回溯
    }
}
int main()
{
   
    cin>>n;
    slove(1);
    cout<<ans<<endl;
}

问题 I: 【搜索】装箱问题

题目
有一个箱子容量为v(正整数,0≤v≤20000),同时有n个物品(0≤n≤30),每个物品有一个体积(正整数)。要求从m个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
输入
第1行两个整数v和n。
第2行n个数,表示n个物品的体积。
输出
一个整数,表示箱子剩余空间。

重要
#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
using namespace std;
int a[35];
int dp[35][20005];
int n,w;
int solve(int index,int val)///记忆化搜索
{
   
    if(dp[index][val]) return dp[index][val];
    if(index>n||val<0) return 0;///到达边界,返回0
    if(val>=a[index])///dp[i][v]=max(dp[i+1][v-a[i]]+a[i],dp[i][v]),选a[i],或者不选a[i]
        dp[index][val]=max(solve(index+1,val),a[index]+solve(index+1,val-a[index]));
    else
        dp[index][val]=solve(index+1,val);
    return dp[index][val];
}
int main()
{
   
    cin>>w>>n;
    for(int i=1;i<=n;i++) cin>>a[i],dp[1][a[i]]=a[i];
    solve(1,w);
    cout<<w-solve(1,w)<<endl;
}

问题 b: 【搜索】素数路

题目:

已知一个四位的素数,要求每次修改其中的一位,并且要保证修改的结果还是一个素数,还不能出现前导零。你要找到一个修改数最少的方案,得到我们所需要的素数。
例如把1033变到8179,这里是一个最短的方案:
1033
1733
3733
3739
3779
8779
8179
修改了6次。

输入

1行,两个四位的素数(没有前导零),表示初始数和目标数。

输出

一个数,表示最少的操作次数。如果不可能,输出“Impossible”。

#include <iostream>
#include <queue>
#include <cstdio>
using namespace std;
int n,m;
int prime[20000];
int a[20000];
int visit[20000];
void getprime()
{
   
    int cnt=0;a[1]=0;
    for(int i=2;i<20000;i++)
    {
   
        if(a[i]==0)prime[cnt++]=i;
        for(int j=0;j<cnt&&prime[j]*i<20000;j++)
        {
   
            a[i*prime[j]]=1;
            if(i%prime[j]==0)break;
        }
    }
}
 
struct node
{
   
    int ori;///原来的数
    int a,b,c,d;///千,百,十,个位
    int sign;///改变了哪一位,防止重复改变同一位
    int step;///步数
}s,t;
queue<node>q;
int bfs(int ori,int a1,int b,int c,int d)
{
   
    getprime();///打表
    q.push({
   ori,a1,b,c,d,0,0});
    while(!q.empty())
    {
   
        t=q.front();q.pop();
        visit[t.ori]=true;
        if(t.ori==m) return t.step;
        for(int i=0;i<=9;i++)
        {
   
            ///获取每一位改变后的数字,记得减去的是t.a,t.b,t.c,t.d,不是a1,b,c,d
            int change1=t.ori-t.a*1000+i*1000,change2
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值