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

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

2.4 最小步数模型

2.4.1 1107. 魔板

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
char g[2][4];
string st,ed;
map<string,int> dis;
map<string,pair<char,string> > pre;
void toM(string str)
{
    for(int i=0;i<4;i++)
    {
        g[0][i]=str[i];
    }
    for(int i=3,j=4;i>=0;i--,j++)
    {
        g[1][i]=str[j];
    }
}
string getStr()
{
    string str="";
    for(int i=0;i<4;i++)
    {
        str+=g[0][i];
    }
    for(int i=3;i>=0;i--)
    {
        str+=g[1][i];
    }
    return str;
}
string opA(string str)
{
    toM(str);
    for(int i=0;i<4;i++)
    {
        swap(g[0][i],g[1][i]);
    }
    return getStr();
}
string opB(string str)
{
    toM(str);
    char v0=g[0][3],v1=g[1][3];
    for(int i=2;i>=0;i--)
    {
        g[0][i+1]=g[0][i];
        g[1][i+1]=g[1][i];
    }
    g[0][0]=v0,g[1][0]=v1;
    return getStr();
}
string opC(string str)
{
    toM(str);
    char v=g[0][1];
    g[0][1]=g[1][1];
    g[1][1]=g[1][2];
    g[1][2]=g[0][2];
    g[0][2]=v;
    return getStr();
}
void bfs(string st)
{
    if(st==ed)
        return;
    queue<string> q;
    q.push(st);
    dis[st]=0;
    while(!q.empty())
    {
        string top=q.front();
        q.pop();
        string tmp[3];
        tmp[0]=opA(top);
        tmp[1]=opB(top);
        tmp[2]=opC(top);
        for(int i=0;i<3;i++)
        {
            if(dis.count(tmp[i])==0)
            {
                dis[tmp[i]]=dis[top]+1;
                pre[tmp[i]]=make_pair(i+'A',top);
                q.push(tmp[i]);
                if(tmp[i]==ed)
                    return;
            }
        }
    }
}
int main()
{
    for(int i=0;i<4;i++)
    {
        g[0][i]='1'+i;
        st+=g[0][i];
    }
    for(int i=3,j=5;i>=0;i--,j++)
    {
        g[1][i]='0'+j;
        st+=g[1][i];
    }
    for(int i=0;i<8;i++)
    {
        char c;
        cin>>c;
        ed+=c;
    }
    bfs(st);
    cout<<dis[ed]<<endl;
    string op="";
    while(st!=ed)
    {
        op+=pre[ed].first;
        ed=pre[ed].second;
    }
    reverse(op.begin(),op.end());
    if(op.length()!=0)
        cout<<op<<endl;
    return 0;
}

2.5 双端队列广搜

2.5.1 175. 电路维修

image.png

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=510;
int T;
int r,c;
char g[N][N];
int dis[N][N];
bool st[N][N];
struct Node{
    int x,y;
}node;
bool judge(int x,int y)
{
    if(x>r||x<0||y>c||y<0)
    {
        return false;
    }
    return true;
}
int bfs()
{
    int X[]={-1,-1,1,1},Y[]={-1,1,1,-1};
    int ix[]={-1,-1,0,0},iy[]={-1,0,0,-1};
    char cs[]="\\/\\/";
    fill(dis[0],dis[0]+N*N,1e9);
    fill(st[0],st[0]+N*N,false);
    deque<Node> q;
    node.x=0,node.y=0;
    dis[0][0]=0;
    q.push_back(node);
    while(!q.empty())
    {
        Node top=q.front();
        q.pop_front();
        if(st[top.x][top.y]) continue;
        st[top.x][top.y]=true;
        for(int i=0;i<4;i++)
        {
            int newX=top.x+X[i],newY=top.y+Y[i];
            if(judge(newX,newY))
            {
                int cx=top.x+ix[i],cy=top.y+iy[i];
                int d=dis[top.x][top.y]+(g[cx][cy]!=cs[i]);
                if(d<dis[newX][newY])
                {
                    dis[newX][newY]=d;
                    node.x=newX,node.y=newY;
                    if(g[cx][cy]!=cs[i])
                    {
                        q.push_back(node);
                    }
                    else q.push_front(node);
                }
            }
        }
    }
    return dis[r][c];
}
int main()
{
    cin>>T;
    while(T--)
    {
        cin>>r>>c;
        for(int i=0;i<r;i++)
        {
            cin>>g[i];
        }
        int ans=bfs();
        if(ans==1e9)
            cout<<"NO SOLUTION"<<endl;
        else
            cout<<ans<<endl;
    }
    return 0;
}

2.6 双向广搜

2.6.1 190. 字串变换

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=10;
int n;
string A,B;
string a[N],b[N];
int extend(queue<string> &q,map<string,int> &ha,map<string,int> &hb,string a[],string b[])
{
    int tmp=ha[q.front()];
    while(!q.empty()&&tmp==ha[q.front()])
    {
        string t=q.front();
        q.pop();
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<t.length();j++)
            {
                if(t.substr(j,a[i].length())==a[i])
                {
                    string r=t;
                    r.replace(j,a[i].length(),b[i]);
                    if(hb.count(r)) return ha[t]+hb[r]+1;
                    if(ha.count(r)) continue;
                    ha[r]=ha[t]+1;
                    q.push(r);
                }
            }
        }
    }
    return 11;
}
int bfs()
{
    queue<string> qa,qb;
    map<string,int> ha,hb;
    ha[A]=0,hb[B]=0;
    qa.push(A);
    qb.push(B);
    int step=0;
    while((!qa.empty())&&(!qb.empty()))
    {
        int t;
        if(qa.size()<qb.size()) t=extend(qa,ha,hb,a,b);
        else t=extend(qb,hb,ha,b,a);
        if(t<=10)
            return t;
        if(++step==10) return -1;
    }
    return -1;
}
int main()
{
    cin>>A>>B;
    string x,y;
    while(cin>>x>>y)
    {
        a[n]=x,b[n]=y,n++;
    }
    int ans=bfs();
    if(ans==-1)
        cout<<"NO ANSWER!";
    else
        cout<<ans;
    return 0;
}

2.7 A*

2.7.1 178. 第K短路

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=1010,E=200010;
typedef pair<int,int> PII;
typedef pair<int,PII> PIII;
int n,m;
int S,T,K;
int h[N],rh[N],e[E],w[E],ne[E],idx;
int dist[N],f[N],cnt[N];
bool st[N];
void add(int h[],int a,int b,int c)
{
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
void djk()
{
    fill(dist,dist+N,1e9);
    dist[T]=0;
    priority_queue<PII,vector<PII>,greater<PII> >heap;
    heap.push(make_pair(0,T));
    while(heap.size())
    {
        PII t=heap.top();
        heap.pop();
        int ver=t.second;
        if(st[ver]) continue;
        st[ver]=true;
        for(int i=rh[ver];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>dist[ver]+w[i])
            {
                dist[j]=dist[ver]+w[i];
                heap.push(make_pair(dist[j],j));
            }
        }
    }
    for(int i=0;i<n;i++)
        f[i]=dist[i];
}
int a_star()
{
    priority_queue<PIII,vector<PIII>,greater<PIII> > heap;
    heap.push(make_pair(dist[S],make_pair(0,S)));
    while(heap.size())
    {
        PIII t=heap.top();
        heap.pop();
        int ver=t.second.second,distance=t.second.first;
        cnt[ver]++;
        if(cnt[T]==K) return distance;
        for(int i=h[ver];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(cnt[j]<K)
            {
                heap.push(make_pair(distance+w[i]+f[j],make_pair(distance+w[i],j)));
            }
        }
    }
    return -1;
}
int main()
{
    cin>>n>>m;
    fill(h,h+N,-1);
    fill(rh,rh+N,-1);
    for(int i=0;i<m;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        add(h,a,b,c),add(rh,b,a,c);
    }
    cin>>S>>T>>K;
    if(S==T) K+=1;
    djk();
    cout<<a_star();
    return 0;
}

2.7.2 179. 八数码

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
char g[3][3];
string a,b="12345678x";
unordered_map<string,pair<char,string> > pre;
void toG(string s)
{
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
        {
            g[i][j]=s[i*3+j];
        }
    }
}
string toS()
{
    string s="";
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
        {
            s+=g[i][j];
        }
    }
    return s;
}
void getXY(int &x,int &y)
{
    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
        {
            if(g[i][j]=='x')
            {
                x=i,y=j;
                return;
            }
        }
    }
}
string opU(string s)
{
    toG(s);
    int x,y;
    getXY(x,y);
    if(x!=0)
    {
        swap(g[x][y],g[x-1][y]);
        return toS();
    }
    else return "";
}
string opD(string s)
{
    toG(s);
    int x,y;
    getXY(x,y);
    if(x!=2)
    {
        swap(g[x][y],g[x+1][y]);
        return toS();
    }
    else return "";
}
string opL(string s)
{
    toG(s);
    int x,y;
    getXY(x,y);
    if(y!=0)
    {
        swap(g[x][y],g[x][y-1]);
        return toS();
    }
    else return "";
}
string opR(string s)
{
    toG(s);
    int x,y;
    getXY(x,y);
    if(y!=2)
    {
        swap(g[x][y],g[x][y+1]);
        return toS();
    }
    else return "";
}
int bfs()
{
    if(a==b)
        return 0;
    queue<string> q;
    q.push(a);
    pre[a]=make_pair('*',"");
    map<int,char> op;
    op[0]='u';
    op[1]='d';
    op[2]='l';
    op[3]='r';
    while(q.size())
    {
        string t=q.front();
        q.pop();
        string tmp[4];
        tmp[0]=opU(t);
        tmp[1]=opD(t);
        tmp[2]=opL(t);
        tmp[3]=opR(t);
        for(int i=0;i<4;i++)
        {
            if(tmp[i]!=""&&pre.count(tmp[i])==0)
            {
                q.push(tmp[i]);
                pre[tmp[i]]=make_pair(op[i],t);
                if(tmp[i]==b)
                    return 1;
            }
        }
    }
    return -1;
}
int main()
{
    for(int i=0;i<9;i++)
    {
        char c;
        cin>>c;
        a+=c;
    }
    int t=bfs();
    if(t==-1)
        cout<<"unsolvable";
    else
    {
        string ans="";
        string tmp=b;
        while(tmp!=a)
        {
            ans+=pre[tmp].first;
            tmp=pre[tmp].second;
        }
        reverse(ans.begin(),ans.end());
        cout<<ans;
    }
    return 0;
}
//2 3 4 1 5 x 7 6 8

2.8 DFS之连通性模型

2.8.1 1112. 迷宫

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=110;
int k,n;
char g[N][N];
int sx,sy,ex,ey;
bool st[N][N];
int X[]={1,-1,0,0},Y[]={0,0,1,-1};
bool judge(int x,int y)
{
    if(x>=n||x<0||y>=n||y<0)
        return false;
    if(g[x][y]=='#'||st[x][y]==true)
        return false;
    return true;
}
bool dfs(int x,int y)
{
    if(g[x][y]=='#')
        return false;
    if(x==ex&&y==ey)
        return true;
    st[x][y]=true;
    for(int i=0;i<4;i++)
    {
        int newX=x+X[i],newY=y+Y[i];
        if(judge(newX,newY))
        {
            if(dfs(newX,newY)) return true;
        }
    }
    return false;
}
int main()
{
    cin>>k;
    while(k--)
    {
        cin>>n;
        for(int i=0;i<n;i++)
        {
            cin>>g[i];
        }
        cin>>sx>>sy>>ex>>ey;
        fill(st[0],st[0]+N*N,false);
        if(sx==ex&&sy==ey&&g[ex][ey]!='#')
            cout<<"YES"<<endl;
        else if(g[sx][sy]=='#'||g[ex][ey]=='#')
        {
            cout<<"NO"<<endl;
        }
        else
        {
            bool flag=dfs(sx,sy);
            if(flag)
                cout<<"YES"<<endl;
            else cout<<"NO"<<endl;
        }
    }
    return 0;
}
/* BFS
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int k,n;
char g[N][N];
int sx,sy,ex,ey;
bool st[N][N];
int X[]={1,-1,0,0},Y[]={0,0,1,-1};
struct Node{
    int x,y;
}node;
bool judge(int x,int y)
{
    if(x>=n||x<0||y>=n||y<0)
        return false;
    if(g[x][y]=='#'||st[x][y]==true)
        return false;
    return true;
}
bool bfs()
{
    if(g[sx][sy]=='#'||g[ex][ey]=='#')
        return false;
    fill(st[0],st[0]+N*N,false);
    queue<Node> q;
    node.x=sx,node.y=sy;
    q.push(node);
    st[sx][sy]=true;
    while(q.size())
    {
        Node t=q.front();
        q.pop();
        for(int i=0;i<4;i++)
        {
            int newX=t.x+X[i],newY=t.y+Y[i];
            if(judge(newX,newY))
            {
                node.x=newX,node.y=newY;
                q.push(node);
                st[newX][newY]=true;
                if(ex==newX&&ey==newY)
                    return true;
            }
        }
    }
    return false;
}
int main()
{
    cin>>k;
    while(k--)
    {
        cin>>n;
        for(int i=0;i<n;i++)
        {
            cin>>g[i];
        }
        cin>>sx>>sy>>ex>>ey;
        if(sx==ex&&sy==ey&&g[ex][ey]!='#')
            cout<<"YES"<<endl;
        else
        {
            bool flag=bfs();
            if(flag)
                cout<<"YES"<<endl;
            else cout<<"NO"<<endl;
        }
    }
    return 0;
}
*/

2.8.2 1113. 红与黑

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=30;
char g[N][N];
int ans;
int n,m;
int sx,sy;
int X[]={0,0,1,-1},Y[]={1,-1,0,0};
bool st[N][N];
bool judge(int x,int y)
{
    if(x>=n||x<0||y>=m||y<0)
        return false;
    if(st[x][y]==true||g[x][y]=='#')
        return false;
    return true;
}
void dfs(int x,int y)
{
    if(st[x][y]) return;
    st[x][y]=true;
    ans++;
    for(int i=0;i<4;i++)
    {
        int newX=x+X[i],newY=y+Y[i];
        if(judge(newX,newY))
        {
            dfs(newX,newY);
        }
    }
    return;
}
int main()
{
    while(true)
    {
        cin>>m>>n;
        if(m==n&&n==0)
            break;
        for(int i=0;i<n;i++)
        {
            cin>>g[i];
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(g[i][j]=='@')
                {
                    sx=i,sy=j;
                }
            }
        }
        ans=0;
        fill(st[0],st[0]+N*N,false);
        dfs(sx,sy);
        cout<<ans<<endl;
    }
    return 0;
}

2.9 DFS之搜索顺序

2.9.1 1116. 马走日

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=10;
int n,m,x,y;
bool st[N][N];
int ans;
int X[]={-1,1,-2,2,-2,2,-1,1},Y[]={-2,-2,-1,-1,1,1,2,2};
void dfs(int x,int y,int cnt)
{
    if(cnt==n*m)
    {
        ans++;
        return;
    }
    st[x][y]=true;
    for(int i=0;i<8;i++)
    {
        int newX=x+X[i],newY=y+Y[i];
        if(newX>=n||newX<0||newY>=m||newY<0) continue;
        if(st[newX][newY]) continue;
        dfs(newX,newY,cnt+1);
    }
    st[x][y]=false;
}
int main()
{
    std::ios::sync_with_stdio(0);
    int T;
    cin>>T;
    while(T--)
    {
        cin>>n>>m>>x>>y;
        ans=0;
        dfs(x,y,1);
        cout<<ans<<endl;
    }
    return 0;
}

相关文章
|
4月前
|
算法
【算法】二分算法——搜索插入位置
【算法】二分算法——搜索插入位置
|
1月前
|
算法 搜索推荐 数据库
二分搜索:高效的查找算法
【10月更文挑战第29天】通过对二分搜索的深入研究和应用,我们可以不断挖掘其潜力,为各种复杂问题提供高效的解决方案。相信在未来的科技发展中,二分搜索将继续发挥着重要的作用,为我们的生活和工作带来更多的便利和创新。
51 1
|
2月前
|
算法 决策智能
基于禁忌搜索算法的VRP问题求解matlab仿真,带GUI界面,可设置参数
该程序基于禁忌搜索算法求解车辆路径问题(VRP),使用MATLAB2022a版本实现,并带有GUI界面。用户可通过界面设置参数并查看结果。禁忌搜索算法通过迭代改进当前解,并利用记忆机制避免陷入局部最优。程序包含初始化、定义邻域结构、设置禁忌列表等步骤,最终输出最优路径和相关数据图表。
|
3月前
|
大数据 UED 开发者
实战演练:利用Python的Trie树优化搜索算法,性能飙升不是梦!
在数据密集型应用中,高效搜索算法至关重要。Trie树(前缀树/字典树)通过优化字符串处理和搜索效率成为理想选择。本文通过Python实战演示Trie树构建与应用,显著提升搜索性能。Trie树利用公共前缀减少查询时间,支持快速插入、删除和搜索。以下为简单示例代码,展示如何构建及使用Trie树进行搜索与前缀匹配,适用于自动补全、拼写检查等场景,助力提升应用性能与用户体验。
71 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进行安全搜索。代码示例中,搜索百度新闻结果并检测是否含有特定字符串。学习这些技术能提升编程效率和性能。
141 1
揭开JavaScript字符串搜索的秘密:indexOf、includes与KMP算法