1.题目描述:
WAJUEJI which home strong!
时间限制:1000 ms | 内存限制:65535 KB
难度:2
-
描述
-
在一个山沟里,姐弟俩同时考上了大学。但由于家里拮据,所以这并不是什么好消息。父亲对孩子说:我就是砸锅卖铁也要把你们姐俩供出来。 当时的姐姐已经决定放弃上学的机会。 没想到第二天天还没亮,弟弟就偷偷带著几件破衣服和几个乾巴馒头走了,在姐姐枕边留下一个纸条: 姐,你别愁了,考上大学不容易,我出去打工供你。弟。 姐姐握著那张字条,趴在炕上,失声痛哭。 那一年,弟弟17岁,姐姐20岁。 姐姐用父亲满村子借的钱和弟弟在工地裏搬水泥挣的钱终於读到了大三。 一天姐姐正在寝室里看书,同学跑进来对姐姐说,有个老乡在找你。姐姐很纳闷,走出去后,远远地看见弟弟,穿著满身是水泥和沙子的工作服。姐姐说,你怎么和我同学说你是我老乡啊? 他笑著说,你看我穿的这样,说是你弟,你同学还不笑话你? 姐姐鼻子一酸,眼泪就落了下来。弟弟赶忙为姐姐擦掉眼泪,说:姐,你别哭,我这次来是想让你帮我打听一下,学挖掘机哪家强?
在你的帮助下,弟弟踏上了去蓝翔的路。
那么问题就来了。
-
输入
- 第一个数T,T组测试数据。
两个数 n, m; ( 0< n , m <= 100 ) 表示一个h行m列的二维地图。
接下来n行每行m 个字符。
‘s’ 表示弟弟目前所在位置。
‘# ’表示此处为一座山。为了节省体力,不从此处通行。
从‘A’-‘Z’表示各地的经济水平,对应1-26,路过对应字符的地区需要交对应的生活费。
‘l’表示蓝翔技校的所在地。
s 与 l 均为小写字母。
弟弟只能走四个方向。
输出 - 输出一个数表示弟弟到达蓝翔需要的生活费最小是多少。
如果不能到达,输出 -1。
样例输入 -
3 3 5 #sVGF A##ZA lCDBC 3 3 sAB ABS ABl 3 3 s#B ### ABl
样例输出 -
48 4 -1
- 第一个数T,T组测试数据。
2.思路要点
本题虽然给的难度评级是2,但是个人感觉不是一道好做的题,考察的知识点非常的全面
本题我们需要用到两个知识点:BFS,优先队列(本题中,博主我手动写堆模拟优先队列,毕竟是一个讨厌STL的boy)
想法:
1.首先我们利用优先队列的BFS的想法的原因是,我们要找出最小代价,所以说,我们不断的用优先队列选择出优先级最高的元素(这里的话,当到该点的权值最小的时候优先级最大),当我们选择出的优先级最高的元素下一步直接就可以到达蓝翔的时候,我们就找到了最小代价,因为其他的BFS方向还在他们的路上~
2.有的同学可能和我一样会发现如果一个点已经被BFS开发过了,但是下一次我们另一条路径也开发到这个点的时候,让该点的权值变少了,那么很显然,这种情况下我们必须要让该点再一次进队列,以保证下一次我们从该点处触发的时候,我们还可以最优
3.由2可见,该题中我们不能用记录数组记录我们的访问了,有的同学可能又要问了,如果不记录的话,我们会不会走回头路,从而导致我们BFS陷入死循环的状态,答案是不会的,因为,我们在判断的时候,附加的条件是要是想要往回走,必须走回去之后可以让最小代价变小,但是走了回头路只会让最小代价变大,轻而易举的解决了这个问题
3.AC代码
#include"iostream"
#include"cstdio"
#include"cstring"
#include"cstdlib"
#define N 10010
using namespace std;
typedef struct node
{
char c;
int x;
int y;
int s;
}point;
typedef struct k
{
int s;
char c;
}w;
int n,m;
int bx,by;
int sum;
point queue[N];
w map[120][120];
int heap[N];
int heapnum;
int nn[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
void swap(int x,int y)
{
int t=heap[x];
heap[x]=heap[y];
heap[y]=t;
}
void siftdown(int i)
{
int t;
while(i*2<=heapnum)
{
if(queue[heap[i]].s>queue[heap[i*2]].s) t=i*2;
else t=i;
if(i*2+1<=heapnum&&queue[heap[i*2+1]].s<queue[heap[t]].s) t=i*2+1;
if(t!=i)
{
swap(i,t);
i=t;
}
else break;
}
}
void siftup(int i)
{
int t;
while(!(i==2||i==3||i==1))
{
if(queue[heap[i]].s<queue[heap[i/2]].s)
{
swap(i,i/2);
i=i/2;
}
else break;
}
}
int bfs(int x,int y)
{
heap[1]=1;
heapnum=1;
int p=1;
int k;
queue[1].x=x;
queue[1].y=y;
queue[1].c='s';
queue[1].s=0;
while(heapnum!=0)
{
for(int i=0;i<4;i++)
{
int dx=queue[heap[1]].x+nn[i][0];
int dy=queue[heap[1]].y+nn[i][1];
if(dx<1||dy<1||dx>n||dy>m||map[dx][dy].c=='#') continue;
else
{
if(map[dx][dy].c=='l') return queue[heap[1]].s;
else
{
k=(int)map[dx][dy].c-64;
if(map[dx][dy].s==0||(queue[heap[1]].s+k)<map[dx][dy].s)
{
heapnum++;
queue[++p].c=map[dx][dy].c;
queue[p].x=dx;queue[p].y=dy;
queue[p].s=queue[heap[1]].s+k;
map[dx][dy].s=queue[p].s;
heap[heapnum]=p;
siftup(heapnum);
}
else continue;
}
}
}
heap[1]=heap[heapnum];
heapnum--;
siftdown(1);
}
return -1;
}
int main()
{
int t;
scanf("%d",&t);getchar();
while(t--)
{
memset(map,0,sizeof(map));
scanf("%d%d",&n,&m);getchar();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%c",&map[i][j].c);
if(map[i][j].c=='s') bx=i,by=j;
}
getchar();
}
int k;
if((k=bfs(bx,by))==-1) printf("-1\n");
else printf("%d\n",k);
}
return 0;
}