【算法提高——第二讲】搜索(3)

简介: 【算法提高——第二讲】搜索(3)

2.9.2 1117. 单词接龙

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=50;
string str[N],start;
int n;
bool st[N];
int ans;
bool judge(string s)
{
    for(int i=0;i<2*n;i++)
    {
        int _min=min(s.length(),str[i].length());
        for(int len=1;len<_min;len++)
        {
            if(s.substr(s.length()-len)==str[i].substr(0,len)&&st[i]==false)
            {
                return true;
            }
        }
    }
    return false;
}
void dfs(string s)
{
    if(judge(s))
    {
        string tmp="";
        for(int i=0;i<2*n;i++)
        {
            int _min=min(s.length(),str[i].length());
            for(int len=1;len<_min;len++)
            {
                if(s.substr(s.length()-len)==str[i].substr(0,len)&&st[i]==false)
                {
                    st[i]=true;
                    tmp=s+str[i].substr(len);
                    dfs(tmp);
                    st[i]=false;
                }
            }
        }
    }
    else
    {
        ans=max(ans,(int)s.length());
        return;
    }
}
int main()
{
    cin>>n;
    for(int i=0;i<n;i++) cin>>str[i];
    for(int i=n;i<2*n;i++) str[i]=str[i-n];
    cin>>start;
    string s="#"+start;
    dfs(s);
    cout<<ans-1<<endl;
    return 0;
}

2.9.3 1118. 分成互质组

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=11;
int n;
int p[N];
int group[N][N];
bool st[N];
int ans=N;
//g:第几组;gc:当前组内下标是什么;
//tc:当前组中共有多少元素;start:当前组可以从哪个下标开始搜
int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}
bool check(int group[],int gc,int i)
{
    for(int j=0;j<gc;j++)
    {
        if(gcd(p[group[j]],p[i])>1)
            return false;
    }
    return true;
}
void dfs(int g,int gc,int tc,int start)
{
    if(g>=ans) return;
    if(tc==n) ans=g;
    bool flag=true;
    for(int i=start;i<n;i++)
    {
        if(!st[i]&&check(group[g],gc,i))
        {
            st[i]=true;
            group[g][gc]=i;
            dfs(g,gc+1,tc+1,i+1);
            st[i]=false;
            flag=false;
        }
    }
    if(flag) dfs(g+1,0,tc,0);
}
int main()
{
    cin>>n;
    for(int i=0;i<n;i++) cin>>p[i];
    dfs(1,0,0,0);
    cout<<ans;
    return 0;
}

2.10 DFS之剪枝与优化

2.10.1 165. 小猫爬山

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=25;
int n,w;
int cat[N];
int sum[N];
bool st[N];
int ans=N;
bool cmp(int a,int b)
{
    return a>b;
}
void dfs(int u,int k)
{
    if(k>=ans) return;
    if(u==n)
    {
        ans=k;
        return;
    }
    for(int i=0;i<k;i++)
    {
        if(cat[u]+sum[i]<=w)
        {
            sum[i]+=cat[u];
            dfs(u+1,k);
            sum[i]-=cat[u];
        }
    }
    sum[k]=cat[u];
    dfs(u+1,k+1);
    sum[k]=0;
}
int main()
{
    cin>>n>>w;
    for(int i=0;i<n;i++) cin>>cat[i];
    sort(cat,cat+n,cmp);
    dfs(0,0);
    cout<<ans;
    return 0;
}

2.10.2 166. 数独

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=9;
char str[100];
int ones[1<<N],mp[1<<N];
int row[N],col[N],cell[3][3];
inline int lowbit(int x)
{
    return x&-x;
}
void init()
{
    for(int i=0;i<N;i++)
    {
        row[i]=(1<<N)-1;
        col[i]=(1<<N)-1;
    }
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
        {
            cell[i][j]=(1<<N)-1;
        }
    }
}
inline int get(int x,int y)
{
    return row[x]&col[y]&cell[x/3][y/3];
}
bool bfs(int cnt)
{
    if(cnt==0) return true;
    int x,y,minv=10;
    for(int i=0;i<N;i++)
    {
        for(int j=0;j<N;j++)
        {
            if(str[i*N+j]=='.')
            {
                int t=ones[get(i,j)];
                if(t<minv)
                {
                    x=i,y=j,minv=t;
                }
            }
        }
    }
    int t=get(x,y);
    for(;t!=0;t-=lowbit(t))
    {
        int n=mp[lowbit(t)];
        row[x]-=1<<n;
        col[y]-=1<<n;
        cell[x/3][y/3]-=1<<n;
        str[x*N+y]='1'+n;
        if(bfs(cnt-1)) return true;
        row[x]+=1<<n;
        col[y]+=1<<n;
        cell[x/3][y/3]+=1<<n;
        str[x*N+y]='.';
    }
    return false;
}
int main()
{
    for(int i=0;i<N;i++) mp[1<<i]=i;
    for(int i=0;i<(1<<N);i++)
    {
        int s=0;
        for(int j=i;j;j-=lowbit(j)) s++;
        ones[i]=s;
    }
    while(true)
    {
        init();
        cin>>str;
        if(str[0]=='e')
            break;
        int cnt=0;
        for(int i=0,k=0;i<N;i++)
        {
            for(int j=0;j<N;j++,k++)
            {
                if(str[k]!='.')
                {
                    int t=str[k]-'1';
                    row[i]-=1<<t;
                    col[j]-=1<<t;
                    cell[i/3][j/3]-=1<<t;
                }
                else cnt++;
            }
        }
        bfs(cnt);
        cout<<str<<endl;
    }
    return 0;
}

2.10.3 167. 木棒

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=70;
int sticks[N];
bool st[N];
int n;
int sum,length;
bool dfs(int u,int cur,int start)
{
    if(u*length==sum) return true;
    if(cur==length) return dfs(u+1,0,0);
    for(int i=start;i<n;i++)
    {
        int l=sticks[i];
        if(st[i]||cur+l>length) continue;
        st[i]=true;
        if(dfs(u,cur+l,i+1)) return true;
        st[i]=false;
        if(!cur||cur+l==length) return false;
        int j=i;
        while(j<n&&sticks[j]==sticks[i]) j++;
        i=j-1;
    }
    return false;
}
int main()
{
    while(true)
    {
        fill(st,st+N,false);
        sum=0,length=0;
        cin>>n;
        if(n==0) break;
        for(int i=0;i<n;i++)
        {
            cin>>sticks[i];
            sum+=sticks[i];
            length=max(length,sticks[i]);
        }
        sort(sticks,sticks+n);
        reverse(sticks,sticks+n);
        while(length<=sum)
        {
            if(sum%length==0&&dfs(0,0,0))
            {
                cout<<length<<endl;
                break;
            }
            length++;
        }
    }
    return 0;
}

2.10.4 168. 生日蛋糕

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=25,INF=1e9;
int n,m;
int minv[N],mins[N];
int R[N],H[N];
int ans=INF;
void dfs(int u,int v,int s)
{
    if(v+minv[u]>n) return;
    if(s+mins[u]>=ans) return;
    if(s+2*(n-v)/R[u+1]>=ans) return;
    if(!u)
    {
        if(v==n) ans=s;
        return;
    }
    for(int r=min(R[u+1]-1,(int)sqrt(n-v));r>=u;r--)
    {
        for(int h=min(H[u+1]-1,(n-v)/r/r);h>=u;h--)
        {
            int t=0;
            if(u==m) t=r*r;
            R[u]=r,H[u]=h;
            dfs(u-1,v+r*r*h,s+2*r*h+t);
        }
    }
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        minv[i]=minv[i-1]+i*i*i;
        mins[i]=mins[i-1]+2*i*i;
    }
    R[m+1]=H[m+1]=INF;
    dfs(m,0,0);
    if(ans==INF) cout<<0<<endl;
    else cout<<ans<<endl;
    return 0;
}

2.11 迭代加深

2.11.1 170. 加成序列

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=110;
int n;
int path[N];
bool dfs(int u,int depth)
{
    if(u==depth) return path[u-1]==n;
    bool st[N]={false};
    for(int i=u-1;i>=0;i--)
    {
        for(int j=i;j>=0;j--)
        {
            int s=path[i]+path[j];
            if(s>path[u-1]&&s<=n&&!st[s])
            {
                st[s]=true;
                path[u]=s;
                if(dfs(u+1,depth)) return true;
            }
        }
    }
    return false;
}
int main()
{
    while(true)
    {
        cin>>n;
        if(n==0) break;
        int depth=1;
        path[0]=1;
        while(!dfs(1,depth)) depth++;
        for(int i=0;i<depth;i++)
        {
            cout<<path[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

2.12 双向DFS

2.12.1 171. 送礼物

image.png


代码:

#include<bits/stdc++.h>
using namespace std;
const int N=50;
typedef long long LL;
int n,m,k;
int g[N];
int weights[1<<24],cnt;
int ans;
void dfs_1(int u,int s)
{
    if(u==k)
    {
        weights[cnt++]=s;
        return;
    }
    if((LL)s+g[u]<=m) dfs_1(u+1,s+g[u]);
    dfs_1(u+1,s);
}
void dfs_2(int u,int s)
{
    if(u==n)
    {
        int l=0,r=cnt-1;
        while(l<r)
        {
            int mid=l+r+1>>1;
            if((LL)weights[mid]+s<=m) l=mid;
            else r=mid-1;
        }
        if(weights[r]+s<=m)
            ans=max(ans,weights[r]+s);
        return;
    }
    if((LL)s+g[u]<=m) dfs_2(u+1,s+g[u]);
    dfs_2(u+1,s);
}
int main()
{
    cin>>m>>n;
    for(int i=0;i<n;i++) cin>>g[i];
    sort(g,g+n);
    reverse(g,g+n);
    k=n/2+2;
    dfs_1(0,0);
    sort(weights,weights+cnt);
    cnt=unique(weights,weights+cnt)-weights;
    dfs_2(k,0);
    cout<<ans;
    return 0;
}

2.13 IDA*

2.13.1 180. 排书

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=15;
int n;
int q[N];
int w[5][N];
int f()
{
    int tot=0;
    for(int i=0;i+1<n;i++)
    {
        if(q[i+1]!=q[i]+1)
            tot++;
    }
    return (tot+2)/3;
}
bool check()
{
    for(int i=0;i<n;i++)
    {
        if(q[i]!=i+1)
            return false;
    }
    return true;
}
bool dfs(int depth,int max_depth)
{
    if(depth+f()>max_depth) return false;
    if(check()) return true;
    for(int len=1;len<=n;len++)
    {
        for(int l=0;l+len-1<n;l++)
        {
            int r=l+len-1;
            for(int k=r+1;k<n;k++)
            {
                memcpy(w[depth],q,sizeof q);
                int x,y;
                for(x=r+1,y=l;x<=k;x++,y++)
                {
                    q[y]=w[depth][x];
                }
                for(x=l;x<=r;x++,y++)
                {
                    q[y]=w[depth][x];
                }
                if(dfs(depth+1,max_depth)) return true;
                memcpy(q,w[depth],sizeof q);
            }
        }
    }
    return false;
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        cin>>n;
        for(int i=0;i<n;i++)
            cin>>q[i];
        int depth=0;
        while(depth<5&&!dfs(0,depth)) depth++;
        if(depth>=5) cout<<"5 or more"<<endl;
        else cout<<depth<<endl;
    }
    return 0;
}

2.13.2 181. 回转游戏

image.png


代码:

#include<bits/stdc++.h>
using namespace std;
const int N=24;
int op[8][7]={
    {0,2,6,11,15,20,22},
    {1,3,8,12,17,21,23},
    {10,9,8,7,6,5,4},
    {19,18,17,16,15,14,13},
    {23,21,17,12,8,3,1},
    {22,20,15,11,6,2,0},
    {13,14,15,16,17,18,19},
    {4,5,6,7,8,9,10}
};
int oppsite[8]={5,4,7,6,1,0,3,2};
int center[8]={6,7,8,11,12,15,16,17};
int q[N];
int path[100];
int sum[4];
int f()
{
    fill(sum,sum+4,0);
    for(int i=0;i<8;i++)
        sum[q[center[i]]]++;
    int k=0;
    for(int i=1;i<=3;i++)
    {
        k=max(k,sum[i]);
    }
    return 8-k;
}
void operate(int x)
{
    int t=q[op[x][0]];
    for(int i=1;i<7;i++)
    {
        q[op[x][i-1]]=q[op[x][i]];
    }
    q[op[x][6]]=t;
}
bool dfs(int depth,int max_depth,int last)
{
    if(depth+f()>max_depth) return false;
    if(f()==0) return true;
    for(int i=0;i<8;i++)
    {
        if(oppsite[i]==last) continue;
        operate(i);
        path[depth]=i;
        if(dfs(depth+1,max_depth,i)) return true;
        operate(oppsite[i]);
    }
    return false;
}
int main()
{
    while(scanf("%d",&q[0]),q[0])
    {
        for(int i=1;i<N;i++)
        {
            scanf("%d",&q[i]);
        }
        int depth=0;
        while(!dfs(0,depth,-1)) depth++;
        if(!depth)
            puts("No moves needed");
        else
        {
            for(int i=0;i<depth;i++)
            {
                printf("%c",path[i]+'A');
            }
            puts("");
        }
        printf("%d\n",q[6]);
    }
    return 0;
}

相关文章
|
4月前
|
算法
【算法】二分算法——搜索插入位置
【算法】二分算法——搜索插入位置
|
1月前
|
算法 搜索推荐 数据库
二分搜索:高效的查找算法
【10月更文挑战第29天】通过对二分搜索的深入研究和应用,我们可以不断挖掘其潜力,为各种复杂问题提供高效的解决方案。相信在未来的科技发展中,二分搜索将继续发挥着重要的作用,为我们的生活和工作带来更多的便利和创新。
50 1
|
2月前
|
算法 决策智能
基于禁忌搜索算法的VRP问题求解matlab仿真,带GUI界面,可设置参数
该程序基于禁忌搜索算法求解车辆路径问题(VRP),使用MATLAB2022a版本实现,并带有GUI界面。用户可通过界面设置参数并查看结果。禁忌搜索算法通过迭代改进当前解,并利用记忆机制避免陷入局部最优。程序包含初始化、定义邻域结构、设置禁忌列表等步骤,最终输出最优路径和相关数据图表。
|
3月前
|
大数据 UED 开发者
实战演练:利用Python的Trie树优化搜索算法,性能飙升不是梦!
在数据密集型应用中,高效搜索算法至关重要。Trie树(前缀树/字典树)通过优化字符串处理和搜索效率成为理想选择。本文通过Python实战演示Trie树构建与应用,显著提升搜索性能。Trie树利用公共前缀减少查询时间,支持快速插入、删除和搜索。以下为简单示例代码,展示如何构建及使用Trie树进行搜索与前缀匹配,适用于自动补全、拼写检查等场景,助力提升应用性能与用户体验。
70 2
|
2月前
|
存储 算法 C++
【搜索算法】 跳马问题(C/C++)
【搜索算法】 跳马问题(C/C++)
|
2月前
|
人工智能 算法 Java
【搜索算法】数字游戏(C/C++)
【搜索算法】数字游戏(C/C++)
|
4月前
|
机器学习/深度学习 算法 文件存储
【博士每天一篇文献-算法】 PNN网络启发的神经网络结构搜索算法Progressive neural architecture search
本文提出了一种名为渐进式神经架构搜索(Progressive Neural Architecture Search, PNAS)的方法,它使用顺序模型优化策略和替代模型来逐步搜索并优化卷积神经网络结构,从而提高了搜索效率并减少了训练成本。
66 9
|
4月前
|
算法
【算法】递归、搜索与回溯——汉诺塔
【算法】递归、搜索与回溯——汉诺塔
|
4月前
|
存储 算法 调度
基于和声搜索算法(Harmony Search,HS)的机器设备工作最优调度方案求解matlab仿真
通过和声搜索算法(HS)实现多机器并行工作调度,以最小化任务完成时间。在MATLAB2022a环境下,不仅输出了工作调度甘特图,还展示了算法适应度值的收敛曲线。HS算法模拟音乐家即兴创作过程,随机生成初始解(和声库),并通过选择、微调生成新解,不断迭代直至获得最优调度方案。参数包括和声库大小、记忆考虑率、音调微调率及带宽。编码策略将任务与设备分配映射为和声,目标是最小化完成时间,同时确保满足各种约束条件。
|
5月前
|
数据采集 算法 JavaScript
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法
JavaScript字符串搜索涵盖`indexOf`、`includes`及KMP算法。`indexOf`返回子字符串位置,`includes`检查是否包含子字符串。KMP是高效的搜索算法,尤其适合长模式匹配。示例展示了如何在数据采集(如网页爬虫)中使用这些方法,结合代理IP进行安全搜索。代码示例中,搜索百度新闻结果并检测是否含有特定字符串。学习这些技术能提升编程效率和性能。
140 1
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法