2018 蓝桥杯省赛 B 组模拟赛(五) F. 结果填空:藏宝图

蒜头君得到一张藏宝图。藏宝图是一个 10 \times 1010×10 的方格地图,图上一共有 1010 个宝藏。有些方格地形太凶险,不能进入。

整个图只有一个地方可以出入,即是入口也是出口。蒜头君是一个贪心的人,他规划要获得所有宝藏以后才从出口离开。

藏宝图上从一个方格到相邻的上下左右的方格需要 11 天的时间,蒜头君从入口出发,找到所有宝藏以后,回到出口,最少需要多少天。

思路:https://blog.csdn.net/qq_33193309/article/details/79702083

#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
char mp[20][20] = {
"1111111211",
"1110112111",
"1011211011",
"1211101121",
"1011210111",
"1101111011",
"1111101121",
"1010112111",
"1211110011",
"1101102111"
};
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};

struct Node {
	int x;
	int y;
	Node(){}
	Node(int _x,  int _y) {x = _x; y = _y;}
}no[20];
int bfs(Node st, Node ed) {
	int vis[20][20];
	memset(vis, 0, sizeof(vis));
	int len[20][20];
	memset(len, 0, sizeof(len));
	queue<Node> q;
	q.push(st);
	vis[st.x][st.y] = 1;
	len[st.x][st.y] = 0;
	while (!q.empty()) {
		Node f = q.front(); q.pop();
		for (int i = 0; i < 4; i++) {
			int xx = f.x + dx[i];
			int yy = f.y + dy[i];
			if (xx < 0 || xx >= 10 || yy < 0 || yy >= 10) continue;
			else if (vis[xx][yy] == 1) continue;
			else if (mp[xx][yy] == '0') continue;
			vis[xx][yy] = 1;
			len[xx][yy] = len[f.x][f.y] + 1;
			if (xx == ed.x && yy == ed.y) return len[xx][yy];
			q.push(Node(xx, yy));
			
		}
	}
}
int main() {
	no[0].x=0,no[0].y=7;
	no[1].x=1,no[1].y=6;
	no[2].x=2,no[2].y=4;
	no[3].x=3,no[3].y=1;
	no[4].x=3,no[4].y=8;
	no[5].x=4,no[5].y=4;
	no[6].x=6,no[6].y=8;
	no[7].x=7,no[7].y=6;
	no[8].x=8,no[8].y=1;
	no[9].x=9,no[9].y=6;
	
	int slen[20][20]; 
	//预处理 每两个宝藏之间的最短距离
	for (int i = 0; i < 10; i++) {
		for (int j = i+1; j < 10; j++) {
			slen[j][i] = slen[i][j] = bfs(no[i], no[j]);
//			cout << slen[j][i] << endl;
		}
	} 
	
	int ans = INF;
	int a[20] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
	
	do {
		Node nn;
		nn.x = 0; nn.y = 0;
		int sum = 0;
		sum += bfs(nn, no[a[0]]);
		for (int i = 0; i < 9; i++) {
			sum += slen[a[i]][a[i+1]];
		}
		sum += no[a[9]].x + no[a[9]].y;//最后回到起点
		ans = min(ans, sum); 
	} while (next_permutation(a, a+10));
	
	cout << ans << endl;
	
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值