首页 > 其他分享 >迭代加深,双向搜索,IDA*,A*,双端队列BFS

迭代加深,双向搜索,IDA*,A*,双端队列BFS

时间:2023-11-02 20:11:39浏览次数:34  
标签:dist int 双端 BFS add maxn 搜索 now IDA

迭代加深:

//迭代加深搜索
//给搜索设定一个范围,如果在这个范围内没有答案那么再加大搜索范围
//这么做是为了防止搜索过深,导致利用大量时间搜索无用信息
//如果当前搜索是第10位,搜索的是个二叉树,那么前9个就是2^0+2^1+2^2+..+2^9=2^10-1,所以时间复杂度并没增大太多
 
//https://www.acwing.com/problem/content/172/

#include<bits/stdc++.h>
using namespace std;
const int N=500;
int path[N],n;
bool dfs(int now,int max_)
{
    if(now>max_) return false;
    if(path[now]==n) return true;
    bool vis[N]={0};
    for(int i=now;i>=1;i--) //剪枝,从大到小搜,可以更快到达目标值
        for(int j=i;j>=1;j--){
            int num=path[i]+path[j];
            if(vis[num]||num<=path[now]||num>n) continue;
            vis[num]=true,path[now+1]=num;
            if(dfs(now+1,max_)) return true;
        } 
    return false;
}
int main()
{
    path[1]=1; 
    while(cin>>n,n){
        int dep=1;
        while(!dfs(1,dep)) dep++;
        for(int i=1;i<=dep;i++) cout<<path[i]<<' ';
        cout<<endl;
    }
    return 0;
}

双端队列-BFS优化搜索(适合0 1状态):

// https://www.luogu.com.cn/problem/P4667

//94 dijkstra
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
bool vis[N];
int n,m,dist[N];
typedef pair<int,int>pii;
int e[N],ne[N],h[N],idx,w[N];
void add(int a,int b,int c)
{
    w[idx]=c,e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
bool dijkstra()
{
    priority_queue<pii,vector<pii>,greater<pii> >que;
    que.push({0,1}),dist[1]=0;
    while(!que.empty()){
        pii now=que.top(); que.pop();
        int x=now.second,y=now.first;
        if(vis[x]) continue; vis[x]=true;
        for(int i=h[x];~i;i=ne[i]){
            int j=e[i];
            if(dist[j]>y+w[i]){
                dist[j]=y+w[i];
                que.push({dist[j],j});
            }
        }
    }
    return (dist[(n+1)*(m+1)]<0x3f3f3f3f/2);
}
int main() 
{
    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=(n+1)*(m+1);i++) dist[i]=0x3f3f3f3f,h[i]=-1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            char x; cin>>x;
            if(x=='/'){
                int u=(m+1)*(i-1)+j+1,v=(m+1)*i+j;
                int u_=u-1,v_=v+1;
                add(u,v,0),add(v,u,0),add(u_,v_,1),add(v_,u_,1);
            }
            else{
                int u=(m+1)*(i-1)+j,v=(m+1)*i+j+1;
                int u_=u+1,v_=v-1;
                add(u,v,0),add(v,u,0),add(u_,v_,1),add(v_,u_,1);
            }
        }
    if(dijkstra()) cout<<dist[(n+1)*(m+1)];
    else cout<<"NO SOLUTION";
    return 0;
}


//双端队列优化
/*
很明显是一道搜索的题。

我们可以把电路板上的每个格点(横线与竖线的交叉点)看作无向图中的结点。
若两个结点x和 y是某个小方格的两个对角,则在 x与 y之间连边。
若该方格中的标准件(对角线)与x到y的线段重合,则边权为 0;若垂直相交,则边权为 1 (说明需要旋转 1 次才能连通)。
然后,我们在这个无向图中求出从左上角到右下角的最短距离,就得到了结果。

这是一个边权要么是 0 ,要么是 1的无向图。在这样的图上,我们可以通过双端队列广度搜索计算。
算法的整体框架与一般的广度优先搜索类似,只是在每个结点上沿分支扩展时稍作改变。
如果这条分支是边权为0的边,就把沿改分支到达的新节点从队头入队;
如果这条分支是边权为1的边,就像一般的广度优先搜索一样从队尾入队。
这样一来,我们就仍然能保证任意时刻广度优先搜索队列中的结点对应的距离值都具有"两段性"和“单调性”
每个结点从队头出队时,就能得到从左上角到该结点的最短距离。

因为每个结点只需要访问一次,所以算法的时间复杂度为O(n×m)。
*/
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=505;
char map[maxn][maxn];
bool used[maxn][maxn];
int dx[4]={1,1,-1,-1},
    dy[4]={1,-1,1,-1};
int n,m,dis[maxn][maxn];
deque< pair<int,int> >q,empty;
bool turn(int x1,int y1,int x2,int y2)
{
    int x=map[(x1+x2)/2][(y1+y2)/2]=='/'?1:-1;
    return x==(y1-y2)/(x1-x2);
}
void bfs()
{
    memset(used,0,sizeof(used));
    memset(dis,0x3f3f3f3f,sizeof(dis));
    q=empty;q.push_back(make_pair(0,0));dis[0][0]=0;//清零!!!
    while(!q.empty())
    {
        int a=q.front().first,
            b=q.front().second;
        q.pop_front();used[a][b]=true;
        for(int i=0;i<4;i++)
        {
            int x=dx[i]+a,y=dy[i]+b;
            if(x<0||n<x||y<0||m<y||used[x][y])
                continue;
            if(turn(a,b,x,y))//如果电线不直接连接两个点,即代价为1
            {//就把结点按正常入队
                dis[x][y]=min(dis[x][y],dis[a][b]+1);//注意要取最小值
                q.push_back(make_pair(x,y));
            }
            else//如果电线直连,那么到(a,b),(x,y)两个点的步数是一样的
            {//换句话说,他们的层级是一样的,由于一般的广搜的队列层级是单调递增的,所以为了保证这个性质,将(x,y)从队首入队.
                dis[x][y]=min(dis[x][y],dis[a][b]);
                q.push_front(make_pair(x,y));
            }
            if(x==n&&y==m) return;
        }
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
            scanf("%s",map[i]);
        if((n+m)%2)
        {
            puts("NO SOLUTION");
            continue;
        }
        bfs();
        printf("%d\n",dis[n][m]);
    }
    return 0;
}

 

标签:dist,int,双端,BFS,add,maxn,搜索,now,IDA
From: https://www.cnblogs.com/o-Sakurajimamai-o/p/17806195.html

相关文章

  • 如何利用 IDataErrorInfo 实现数据校验
    一、定义:ValidatesOnDataErrors是一种在WPF中实现数据校验的方式,可以通过在XAML中设置属性ValidatesOnDataErrors为True来启用。二、使用:① 在ViewModel中实现IDataErrorInfo接口,该接口定义了两个属性:Error和Item[stringcolumnName]——Error属性返回......
  • [PG] Function Candidates Selection Algorithm
    FunctionCandidatesSelectionAlgorithmenvironmentsetupInlightdborafceextension,executesqlbelow,CREATEDOMAINoracle.clobASTEXT;--version1CREATEFUNCTIONoracle.btrim(text,text)RETURNStextAS'btrim'LANGUAGEinternalSTRICT......
  • Before You Install Flask...Watch This! Flask Fridays #1
    flask官网:https://flask.github.net.cn/ git官网:https://git-scm.com/ 建立文件: 建立虚拟环境、激活: sourcevirt/Scripts/activate建立文件: touchhello.py以项目方式打开: fromflaskimportFlask,render_template#创建一个flask实例app=Flask(_......
  • BOSHIDA DC电源模块如何承受超负荷电流的能力
    BOSHIDADC电源模块如何承受超负荷电流的能力DC电源模块是现代电子设备中必不可少的部件,它们通常被用来将交流电转换为稳定的直流电,为电子设备提供所需的电力。在某些情况下,DC电源模块可能会遇到超负荷电流的情况,如启动过程中或异常负载等。因此,DC电源模块必须具备承受超负荷电流......
  • 字符串、线性表、队列、栈、哈希表、dfs、bfs
    题目列表:1.字符串无重复字符的最长子串(中等难度)给定一个字符串s,请你找出其中不含有重复字符的最长子串的长度。AC代码,展开查看classSolution{public:intlengthOfLongestSubstring(strings){intres=0;unordered_map<char,int>heap......
  • BOSHIDA 散热问题在DC电源模块设计中的重要性和解决方法
    BOSHIDA散热问题在DC电源模块设计中的重要性和解决方法随着电子科技的快速发展,直流(DC)电源模块被广泛应用于各种电子设备和系统中。但是,由于工作时会产生热量,高功率元器件的散热问题一直是DC电源模块设计和制造中的一个重要问题。如果不解决散热问题,会导致系统的性能下降、寿命缩......
  • BOSHIDA DC电源模块的短期过载能力
    BOSHIDADC电源模块的短期过载能力DC电源模块是一种专门用来将交流电源转换为稳定直流电源的电子元件,适用于各种场合,如电子产品制造、通信、无线电、医疗等。在使用DC电源模块时,短期过载能力是考察其质量的重要指标之一。短期过载能力是指DC电源模块在短时间内承受超负荷电流的......
  • Java双端队列Deque简述
    概述​ Deque是一个双端队列接口,继承自Queue接口,Deque的实现类是LinkedList、ArrayDeque、LinkedBlockingDeque,其中LinkedList是最常用的。​ Deque是一个线性collection,支持在两端插入和移除元素。名称deque是“doubleendedqueue(双端队列)”的缩写,通常读为“deck”。大多数......
  • 节奏达人疯狂猜歌双端流量主小程序开发
    节奏达人疯狂猜歌双端流量主小程序开发流量主小程序千千万,可以长期运营且留存高的,猜歌小程序必有一席之地。好运营:依靠社交属性,可以快速短时间裂变。依靠短视频可以快速吸引玩家。活跃度高,粘性高,利于长期运营。最新开发资讯:1、双端支持(已上线),2、闯关模式(已上线),3、爱豆模式(已上线),4、......
  • ida/idr-1—文档翻译
    一、msm-5.4/Documentation/core-api/idr.rst翻译概述========要解决的一个常见问题是分配标识符(ID);通常用很小的数字来标识一个事物。示例包括文件描述符、进程ID、网络协议中的数据包标识符、SCSI标签和设备实例号。IDR和IDA为该问题提供了合理的解决方案,以避免每......