AOJ 0558 チーズ (Cheese)

本来不打算更博客,但是这个题还是蛮有意思的

题目链接:https://onlinejudge.u-aizu.ac.jp/challenges/search/titles/0558

题目的大体意思:一个小老鼠想吃奶酪,但是在走图的过程中会碰到一些东西,当然,奶酪有本身的硬度,需要达到一定的生命值才能吃,初始的时候小老鼠的生命值是1

给定一张图,输入一些字符,'.'表示可以走的空地,‘x’代表走不通的障碍物,数字代表奶酪所代表的硬度,达不到生命值是不能吃比他生命值大的奶酪,

题目要求小老鼠吃完所有奶酪所用的最小步数

题目唯一的难点在于如何处理奶酪和生命值的关系

我们可以发现,要想吃完所有奶酪就要求生命值达标,换言之就是小老鼠吃奶酪的顺序是从小到大挨个吃的;

也就是说,我们可以将问题转化成小老鼠吃完当前奶酪在吃下一个比当前奶酪硬度大一的奶酪,这样就

转化成了在bfs中不断变化起点和终点的一个问题;

我们就只需要在普通bfs的基础上处理起点和终点的关系:

参考代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int INF=0x3f3f3f3f;
 4 int h,w,n;
 5 char mp[1010][1010];
 6 int sx,sy;
 7 int fx,fy;
 8 int minn;
 9 int dir[4][2]=
10 {
11     {-1,0},
12     {0,-1},
13     {1,0},
14     {0,1},
15 };
16 struct node
17 {
18     int x;
19     int y;
20 };
21 bool check(int tx,int ty)
22 {
23     if(tx<0||tx>=h||ty<0||ty>=w)
24     {
25         return false;
26     }
27     return true;
28 }
29 int dis[1010][1010];//表示起点到终点的距离
30 int  bfs(int tx,int ty,char ch)
31 {
32     memset(dis,0,sizeof(dis));//需要将起点到终点的距离每次初始化表示没走过
33     node start,next;
34     queue<node>q;
35     start.x=tx;
36     start.y=ty;
37     q.push(start);
38     while(!q.empty())
39     {
40         start=q.front();
41         q.pop();
42         if(mp[start.x][start.y]==ch)//碰到终点的数字停止
43         {
44             fx=start.x;//重置终点
45             fy=start.y;
46             break ;
47         }
48         
49         for(register int i=0;i<4;i++)
50         {
51             next.x=start.x+dir[i][0];
52             next.y=start.y+dir[i][1];
53             if(check(next.x,next.y)&&mp[next.x][next.y]!='X'&&dis[next.x][next.y]==0)
54             {
55                 dis[next.x][next.y]=dis[start.x][start.y]+1;
56                 q.push(next);
57             }
58         }
59     }
60     sx=fx;//重置终点
61     sy=fy;
62     return dis[fx][fy];
63 }
64 int main()
65 {
66     cin>>h>>w>>n;
67     for(register int i=0;i<h;i++)
68     {
69         for(register int j=0;j<w;j++)
70         {
71             cin>>mp[i][j];
72             if(mp[i][j]=='S')
73             {
74                 sx=i;//初始化起点
75                 sy=j;
76             }
77         }
78     }
79     for(register int i=1;i<=n;i++)//从1到n即可,因为吃奶酪的顺序是顺次递增的
80     minn+=bfs(sx,sy,i+'0');//碰到数字挨个从上一个起点开始到当前位置(终点)
81     cout<<minn<<endl;
82     return 0;
83 }

总结:

1.需要注意的起点和终点关系的置换

2.在者是认识到没有足够的生命值吃不了高级的奶酪,需要顺次去吃

3.bfs的相关操作

posted @ 2022-07-04 20:29  江上舟摇  阅读(25)  评论(0编辑  收藏  举报