蓝桥杯训练day6

bfs,dfs,拓扑排序,dijkstra

  • 1.bfs
    • (1)844. 走迷宫
    • (2)845. 八数码
  • 2.dfs
    • (1)3502. 不同路径数
    • (2)843. n-皇后问题
  • 3.拓扑排序
    • (1)848. 有向图的拓扑序列
    • (2)1191. 家谱树

1.bfs

(1)844. 走迷宫

蓝桥杯训练day6_第1张图片

#include 
#include 
#include 
#include 

using namespace std;

typedef pair<int, int> PII;   //记录一对数据

const int N = 110;

int n, m;
int g[N][N], d[N][N];   //g表示地图,d表示两点之间的距离

int bfs()
{
    queue<PII> q;

    memset(d, -1, sizeof d);
    d[0][0] = 0;
    q.push({0, 0});

    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};   //4个方向

    while (q.size())  //bfs模板题
    {
        auto t = q.front();
        q.pop();

        for (int i = 0; i < 4; i ++ )
        {
            int x = t.first + dx[i], y = t.second + dy[i];

            if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1)  //越界
            {
                d[x][y] = d[t.first][t.second] + 1;
                q.push({x, y});
            }
        }
    }

    return d[n - 1][m - 1];
}

int main()
{
    cin >> n >> m;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < m; j ++ )
            cin >> g[i][j];

    cout << bfs() << endl;

    return 0;
}

(2)845. 八数码

蓝桥杯训练day6_第2张图片

#include 
#include 
#include 
#include 

using namespace std;

int bfs(string state)
{
    queue<string> q;
    unordered_map<string, int> d;   //用哈希表存储状态

    q.push(state);
    d[state] = 0;

    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

    string end = "12345678x";
    while (q.size())
    {
        auto t = q.front();
        q.pop();

        if (t == end) return d[t];

        int distance = d[t];
        int k = t.find('x');
        int x = k / 3, y = k % 3;  //将字符串想象成一个3x3网格,找到x的坐标
        for (int i = 0; i < 4; i ++ )
        {
            int a = x + dx[i], b = y + dy[i];
            if (a >= 0 && a < 3 && b >= 0 && b < 3)
            {
                swap(t[a * 3 + b], t[k]);  //交换位置
                if (!d.count(t))  //看哈希表是否记录过该状态
                {
                    d[t] = distance + 1;
                    q.push(t);
                }
                swap(t[a * 3 + b], t[k]);
            }
        }
    }

    return -1;
}

int main()
{
    char s[2];

    string state;
    for (int i = 0; i < 9; i ++ )
    {
        cin >> s;
        state += *s;
    }

    cout << bfs(state) << endl;

    return 0;
}

2.dfs

(1)3502. 不同路径数

蓝桥杯训练day6_第3张图片
dfs所有路径,然后使用set判重

#include
#include
#include
using namespace std;

const int N=10;

int n,m,k;
int g[N][N];

unordered_set<int>S;

int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};

void dfs(int x,int y,int u,int num) 
{
    if(u==k)
        S.insert(num);  //自动判重
        
    else
    {
        for(int i=0;i<4;i++)
        {
            int a=x+dx[i];
            int b=y+dy[i];
            if(a>=0&&b>=0&&a<n&&b<m)
                dfs(a,b,u+1,num*10+g[a][b]);
        }
    }
}


int main()
{
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < m; j ++ )
            scanf("%d", &g[i][j]);

    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < m; j ++ )
            dfs(i, j, 0, g[i][j]);

    printf("%d\n", S.size());
    return 0;
}

(2)843. n-皇后问题

蓝桥杯训练day6_第4张图片

经典问题,但是要考试了,先不写了,考完蓝桥杯细细说

#include
#include
using namespace std;


const int N=11;
char g[N][N];

int col[1000],ll[1000],rr[1000];



int n;

void  dfs(int u)
{
    if(u==n)
    {
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
                cout<<g[i][j];
            cout<<endl;
        }
        cout<<endl;
        return ;
    }
    
    for(int i=0;i<n;i++)
    {
        if(col[i]||ll[n+u-i]||rr[u+i])continue;  //col表示行,ll表示斜率为-1,r表示斜率为1的直线
        col[i]=ll[n+u-i]=rr[u+i]=1;
        g[u][i]='Q';
        dfs(u+1);
        g[u][i]='.';
        col[i]=ll[n+u-i]=rr[u+i]=0;
    }
}

int main()
{
    cin>>n;
    
    memset(g,'.',sizeof g);
    dfs(0);
    
    return 0;
    
}

3.拓扑排序

(1)848. 有向图的拓扑序列

蓝桥杯训练day6_第5张图片

#include
#include

using namespace std;

const int N=1e5+10,M=2*N;

int h[N],e[M],ne[M],idx;
int d[N];

int q[N];

int n,m;

void add(int a,int b)
{
    e[idx]=b;
    ne[idx]=h[a];
    h[a]=idx++;
}

int topsort()
{
    int tt=-1,hh=0;
    for(int i=1;i<=n;i++)
    {
        if(!d[i])
            q[++tt]=i;
    }
    
    while(hh<=tt)
    {
        int t=q[hh++];
        
        for(int i=h[t];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(--d[j]==0)
            {
                q[++tt]=j;
            }
        }
    }
    
    return tt==n-1;   //表示放了n个节点(0-n-1)
    
}
int main()
{
    cin>>n>>m;
    memset(h,-1,sizeof h);
    for(int i=0;i<m;i++)
    {
        int a,b;
        cin>>a>>b;
        add(a,b);
        d[b]++;
    }
    
    if(!topsort())
        cout<<"-1";
        
    else
    {
        for(int i=0;i<n;i++)
            cout<<q[i]<<" ";
    }
    return 0;
}

(2)1191. 家谱树

蓝桥杯训练day6_第6张图片

#include
#include
using namespace std;
const int N=111,M=N*N;
int e[M],ne[M],h[N],idx;
int n;
int d[N],q[N];

inline void add(int a,int b)
{
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

void topsort()
{
    int hh=0,tt=-1;
    for(int i=1;i<=n;i++)
    if(d[i]==0)
    q[++tt]=i;
    
    while(hh<=tt)
    {
        int t=q[hh++];
        for(int i=h[t];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(--d[j]==0)
            q[++tt]=j;
        }
    }
}

int main()
{
    cin>>n;
    memset(h,-1,sizeof h);
    for(int i=1;i<=n;i++)
    {
        int j;
        while(cin>>j,j)
        add(i,j),d[j]++;
    }
    topsort();
    for(int i=0;i<n;i++)
    cout<<q[i]<<" ";
    return 0;
}

你可能感兴趣的:(蓝桥杯,深度优先,算法)