【计蒜客】2018 蓝桥杯省赛 B 组模拟赛(五) ---- 结果填空:藏宝图

这里写图片描述

思路: 自己还是做题做的少呀,一位一次BFS就够了,没有那么简单。这个题目要求出每两个宝藏之间(把起点也算进去)的最短距离, 共计 11 个点,然后枚举,找到最短的一条回路(环)。这样子其实就是把这个藏宝图上的藏宝点和起点看成一张新的地图,构建成了无向图。这样子就很容易得到结果了。 感谢@zudikn 超霸的指点~

AC代码:

#include <iostream>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
struct Node
{
    int x;
    int y;
};
int edge[15][15];
int llen[15][15];
bool vis[15][15];
int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
int bfs(Node st,Node en)
{
    int len[15][15] ;
    memset(len,0,sizeof(len));
    memset(vis,false,sizeof(vis));
    Node now;
    Node nex;
    queue<Node> q;
    while(!q.empty())
        q.pop();
    q.push(st);
    vis[st.x][st.y] = true;
    while(!q.empty())
    {
        now = q.front();
        q.pop();
        for(int i=0;i<4;i++)
        {
            nex.x = now.x+dir[i][0];
            nex.y = now.y+dir[i][1];
            if(nex.x>=0 && nex.x<10 && nex.y>=0 && nex.y<10 && !vis[nex.x][nex.y] && edge[nex.x][nex.y] != -1)
            {
                len[nex.x][nex.y] = len[now.x][now.y]+1;
                vis[nex.x][nex.y] = true;
                if(nex.x == en.x && nex.y == en.y) return len[nex.x][nex.y];
                q.push(nex);
            }
        }
    }
}
int main()
{
    freopen("in.txt","r",stdin);
    Node n[15]; //预处理
    n[0].x = 0,n[0].y = 0;
    n[1].x = 0,n[1].y = 7;
    n[2].x = 1,n[2].y = 6;
    n[3].x = 2,n[3].y = 4;
    n[4].x = 3,n[4].y = 1;
    n[5].x = 3,n[5].y = 8;
    n[6].x = 4,n[6].y = 4;
    n[7].x = 6,n[7].y = 8;
    n[8].x = 7,n[8].y = 6;
    n[9].x = 8,n[9].y = 1;
    n[10].x = 9,n[10].y = 6;
    memset(llen,0,sizeof(llen));
    for(int i=0;i<10;i++)
    {
        for(int j=0;j<10;j++)
            cin>>edge[i][j];
    }
    for(int i=0;i<=10;i++)
    {
        for(int j=i+1;j<=10;j++)
        {
            llen[i][j] = bfs(n[i],n[j]); //点,两两之间进行BFS,确定每两个点之间的最短距离
            llen[j][i] = llen[i][j];//构建成一个无向图
        }
    }
    int a[10] = {1,2,3,4,5,6,7,8,9,10};
                // 0 1 2 3 4 5 6 7 8 9
    int minn = 0x3f3f3f3f;
    do{
        int sum = 0;
        sum=llen[0][a[0]]+llen[a[9]][0];
        for(int i=1;i<10;i++)
            sum+=llen[a[i-1]][a[i]];
        minn = min(sum,minn);
    }while(next_permutation(a,a+10));
    cout<<minn<<endl;
    return 0;
}
/*
0 0 0 0 0 0 0 1 0 0
0 0 0 -1 0 0 1 0 0 0
0 -1 0 0 1 0 0 -1 0 0
0 1 0 0 0 -1 0 0 1 0
0 -1 0 0 1 0 -1 0 0 0
0 0 -1 0 0 0 0 -1 0 0
0 0 0 0 0 -1 0 0 1 0
0 -1 0 -1 0 0 1 0 0 0
0 1 0 0 0 0 -1 -1 0 0
0 0 -1 0 0 -1 1 0 0 0
*/
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值