列表

详情


NC21724. huizhang要约会

描述

某天某gouhuizhang想要在机房找人去约会,大家吓的四处乱串。为了逃避约会,大家需要在机房合成秘宝隐身衣。
其实机房是一个n*m的矩阵,标记为'.'的格子可以任意移动,标记为'#'的格子是障碍物,你所在的起点标号为'S'。众(wo)所(xia)周(bian)知(de),合成隐身衣需要三瓶快乐水,分别位于标号为'X','Y','Z处。唯一可以合成隐身衣的地方在标号为'E'处。
你每秒只能移动一个单位的距离,每次只能选择向上下左右四个方向移动。每次移动消耗1体力值。
你不能移动到矩阵外面去!神奇的快乐水还有着神奇的原力哦。快乐水X,Y,Z对应的原力分别为a,b,c。带着快乐水移动每步所需要的消耗为你携带的快乐水中原力的最大值加上固定体力消耗值1。
点可以重复经过,路过位于快乐水的格子时你可以选择拿起或不拿起。但是快乐水只要拿起就不能放下。
狗急都会跳墙,so当你没有集齐三瓶快乐水时,你是可以移动到障碍物上面去的。但是你一旦集齐三瓶快乐水,你就不能移动到障碍物上!!!
为了逃避约会,请聪明的你帮助大家计算合成隐身衣的最小体力值消耗是多少?

输入描述

第一行输出t,代表数据组数。()
每组数据的第一行两个整数表示n,m()。
接下来n行,每行m个字符,描述机房地形。
下面一行三个整数a, b, c()。

输出描述

对每组数据输出合成隐身衣的最小体力值消耗(保证有解)。

示例1

输入:

4
3 5
##S##
X#Y#Z
##E##
1 5 4
2 4
SXY#
E..Z
3 2 1
2 4
SXY#
E..Z
1 2 3
3 5
S.##Z
X#Y.#
##E.#
1 5 3

输出:

27
19
21
29

说明:

第一组样例最佳解法:S -> X –> Z -> Y -> E。
路线为:(1,3),(2,3),(2,2),(2,1),(2,2),(2,3),(2,4),(2,5),(2,4),(2,3),(3,3)。
答案为27。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 62ms, 内存消耗: 608K, 提交时间: 2018-12-27 16:27:32

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int T;
int n,m;
char s[105][105];
int vis[105][105];
struct node{
	int x,y,step;
	node(int t1,int t2,int t3){
		x=t1,y=t2,step=t3;
	}
};
int dx[10]={0,0,1,-1};
int dy[10]={1,-1,0,0};
int check(int x,int y){
	if(x<1||x>n||y<1||y>m)return 0;
	return 1;
}
int bfs(int sx,int sy,int ex,int ey,int v,int tp){
	queue<node>q;
	q.push(node(sx,sy,0));
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			vis[i][j]=0;
		}
	}
	while(!q.empty()){
		node cur=q.front();q.pop();
		if(cur.x==ex&&cur.y==ey)return cur.step;
		for(int i=0;i<4;i++){
			int nx=cur.x+dx[i];
			int ny=cur.y+dy[i];
			if(!check(nx,ny)||vis[nx][ny])continue;
			if(!tp&&s[nx][ny]=='#')continue;
			vis[nx][ny]=1;
			q.push(node(nx,ny,cur.step+v));
		}
	}
	return 1e8;
}
int x[5],y[5],c[5],v[5],ans;
void dfs(int time,int sx,int sy,int res,int sum){
	if(time==4){
		res+=bfs(sx,sy,x[4],y[4],sum,0);
		ans=min(ans,res);
		return;
	}
	for(int i=1;i<=3;i++){
		if(!c[i]){
			c[i]=1;
			int tmp=res+bfs(sx,sy,x[i],y[i],sum,1);
			dfs(time+1,x[i],y[i],tmp,max(sum,v[i]+1));
			c[i]=0;
		}
	}
}
int main(){
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++){
			scanf("%s",s[i]+1);
			for(int j=1;j<=m;j++){
				if(s[i][j]=='S'){
					x[0]=i,y[0]=j;
				}
				if(s[i][j]=='X'){
					x[1]=i,y[1]=j;
				}
				if(s[i][j]=='Y'){
					x[2]=i,y[2]=j;
				}
				if(s[i][j]=='Z'){
					x[3]=i,y[3]=j;
				}
				if(s[i][j]=='E'){
					x[4]=i,y[4]=j;
				}
			}
		}
		for(int i=1;i<=3;i++){
			scanf("%d",&v[i]);
		}
		ans=1e8;
		dfs(1,x[0],y[0],0,1);
		printf("%d\n",ans);
	}
}

C++11(clang++ 3.9) 解法, 执行用时: 56ms, 内存消耗: 352K, 提交时间: 2018-12-23 16:05:17

#include<bits/stdc++.h>
using namespace std;
struct node
{
	int x,y,step;
	node(int t1,int t2,int t3)
	{
		x=t1,y=t2,step=t3;
	}
};
char s[105][105];
int vis[105][105],n,m;
int mv[4][2]={1,0,-1,0,0,1,0,-1};

bool check(int x,int y)
{
	if(x<1||x>n||y<1||y>m)return 0;
	return 1;
}
int bfs(int sx,int sy,int tx,int ty,int v,int tp)
{
	queue<node>q;
	q.push(node(sx,sy,0));
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)vis[i][j]=0;
	while(!q.empty())
	{
		node e=q.front();q.pop();
		if(e.x==tx&&e.y==ty)
		return e.step;
		for(int i=0;i<4;i++)
		{
			int xx=e.x+mv[i][0];
			int yy=e.y+mv[i][1];
			
			if(!check(xx,yy)||vis[xx][yy])continue;
			if(!tp&&s[xx][yy]=='#')continue;
			
			vis[xx][yy]=1;
			q.push(node(xx,yy,e.step+v));
		}
	}
	return 1e8;
}
int x[5],y[5],ans,c[5],v[5];
void dfs(int time,int sx,int sy,int res,int sum)
{
	if(time==4)
	{
		res+=bfs(sx,sy,x[4],y[4],sum,0);
		ans=min(ans,res);
		return;
	}
	for(int i=1;i<=3;i++)
	if(!c[i])
	{
		c[i]=1;
		int tmp=res+bfs(sx,sy,x[i],y[i],sum,1);
		dfs(time+1,x[i],y[i],tmp,max(sum,v[i]+1));
		c[i]=0;
	}
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		cin>>n>>m;
		for(int i=1;i<=n;i++)
		{
			scanf("%s",s[i]+1);
			for(int j=1;j<=m;j++)
			if(s[i][j]=='S')
			x[0]=i,y[0]=j;
			else if(s[i][j]=='X')
			x[1]=i,y[1]=j;
			else if(s[i][j]=='Y')
			x[2]=i,y[2]=j;
			else if(s[i][j]=='Z')
			x[3]=i,y[3]=j;
			else if(s[i][j]=='E')
			x[4]=i,y[4]=j;
		}
		for(int i=1;i<=3;i++)scanf("%d",&v[i]);
		ans=1e8;
		dfs(1,x[0],y[0],0,1);
		printf("%d\n",ans);
	}
	return 0;
}

上一题