2022-08-09 算法学习——解答树,广搜分层

解答树

子集枚举 + dfs形成了解答树,对于一个状态,有选择
和不选择两种情况,分别递归,注意选择后的递归,
在递归回溯后一定要清空状态

广搜分层(马的遍历)

!!注意!empty后的前三句话怎么写,这样就可以达到
每层都会分开了,结构更清晰,广搜的模板

#include<bits/stdc++.h>
using namespace std;
int n,m,x,y;
int vis[410][410];
int d[410][410];
struct Node {
    int x,y;
};
int step;
queue < Node > q;
int dir[8][2] = {{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1},{2,1},{1,2}};
int main() {
    scanf("%d%d%d%d",&n,&m,&x,&y);
    memset(d,-1,sizeof(d));
    n+=2;m+=2;x+=2;y+=2;
    q.push(Node{x,y});
    vis[x][y] = 1;
    d[x][y] = 0;
    while(!q.empty()) {
        step++;
        int len = q.size();
        for(int j=0;j<len;j++) {
            int nx = q.front().x;
            int ny = q.front().y;
            q.pop();

            for(int i=0;i<8;i++) {
                int xx = nx + dir[i][0];int yy = ny + dir[i][1];
                if(!vis[xx][yy] && xx<=n && yy<=m && xx>=3 && yy >=3) {
                    vis[xx][yy] = 1;
                    d[xx][yy] = step; // 解决问题的部分
                    q.push(Node{xx,yy});
                }

            }
        }
    }
    for(int i=3;i<=n;i++) {
        for(int j=3;j<=m;j++) {
            printf("%-5d",d[i][j]);
        }
        printf("\n");
    }
    return 0;
}


某些点随着深度的增加而不能被扩展,意思就是在状态转移时,它被扩展有时间限制

#include<bits/stdc++.h>
using namespace std;
int m;
int vis[310][310],miss[310][310];
int dir[5][2] = {{0,0},{1,0},{0,1},{-1,0},{0,-1}};
queue < pair< int,int > >q;
int deep;
int ans[310][310];
int res = 100000;
int main() {
    scanf("%d",&m);
    memset(miss,0x7f,sizeof(miss));
    memset(ans,-1,sizeof(ans));
    for(int i=0;i<m;i++) {
        int xx,yy,t;
        scanf("%d%d%d",&xx,&yy,&t);
        for(int j=0;j<5;j++) {
            miss[ xx + dir[j][0] ][ yy + dir[j][1] ] = min(miss[ xx + dir[j][0] ][ yy + dir[j][1] ],t );
        }
    }
    q.push(make_pair(0,0));
    vis[0][0] = 1;
    ans[0][0] = 0;
    while(!q.empty()) {
        int len = q.size();
        for(int i=0;i<len;i++) {
            int x = q.front().first;
            int y = q.front().second;
            q.pop();
            for(int j=1;j<5;j++) {
                int xx = x+dir[j][0];
                int yy = y+dir[j][1];
                if(!vis[xx][yy] && xx >= 0 && yy >= 0 && miss[xx][yy] > deep+1) {
                    vis[xx][yy] = 1;
                    ans[xx][yy] = deep + 1;
                    q.push(make_pair(xx,yy));
                }
            }
        }
        deep++;
    }
//    cout<<ans[0][4]<<" "<<miss[0][3]<<endl;
    for(int i=0;i<310;i++) {
        for(int j=0;j<310;j++) {
            if(miss[i][j] > 1000 && ans[i][j] != -1) {
                res = min( res,ans[i][j] );
            }
        }
    }
    if(res == 100000) {
        printf("-1");
    }
    else printf("%d",res);
    return 0;
}


posted @   lovevivi121  阅读(5)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示