• 牛客小白月赛61-C-小喵觅食


    题目描述 
    The__Flash 回到家迫不及待地跟 PLMM 分享买回来的零食,PLMM 拿起一包小鱼干正准备要吃,这时恰巧有一只小喵在觅食,引起了 PLMM 的注意。
    现实世界可以抽象为一张 n×m大小的二维地图。PLMM 的初始坐标在(x1​,y1​),活动范围 r1表示 PLMM 只会移动到坐标为 (x,y)的位置 (0≤∣x−x1∣+∣y−y1∣≤r1)。小喵的初始坐标在 (x2,y2),鼻子灵敏度 r2 表示小喵只能闻到坐标为 (x,y)的位置的小鱼干 (0≤∣x−x2∣+∣y−y2∣≤r2)。此外,地图中存在若干障碍物使得 PLMM 和小喵无法通过。

    若 PLMM 或小喵当前的坐标为 (x,y),则下一步可以移动到 (x−1,y), (x,y−1), (x+1,y)(x-1,y),坐标的位置。起初,小喵保持原地不动,但当闻到小鱼干的气味时便会朝 PLMM 的位置跑去。在小喵开始移动的同时,PLMM 会担心吓跑小喵从而保持原地不动。需要注意的是,鼻子灵敏度 r2只能决定小喵能否闻到小鱼干的气味,对小喵的移动范围没有限制。小喵闻到小鱼干气味后便会锁定 PLMM 的位置,即使之后闻不到小鱼干的位置,也会继续朝 PLMM 的位置移动。

    若小喵可以吃到小鱼干,PLMM 想知道自己与小喵移动的距离和最小值。

    输入描述 
    一行输入两个整数 n,m (1≤n,m≤103)。第二行输入两个整数 r1,r2 (1≤r1,r2≤max(n,m))。
    接下来输入 n行,每行输入一个长度为 m 的字符串 s[i]表示二维地图。s[i][j] (s[i][j]∈{′P′,′M′,′∗′,′.′})表示地图坐标为 (i,j) (1≤i≤n,1≤j≤m)的位置,其中 ′P′表示 PLMM 的初始位置,′M′ 表示小喵的初始位置,′∗′ 表示障碍物不允许通过,′.′ 表示空地允许通过。
    保证地图中字符 ′P′ 有且仅有一个,字符 ′M′有且仅有一个。

    输出描述 

    若小喵可以吃到小鱼干则输出 PLMM 与小喵移动的距离和最小值,否则输出 -1。

    输入

    1. 5 3
    2. 2 1
    3. ...
    4. .M.
    5. ...
    6. ...
    7. .P.

    输出

    3

    解析:我们可以直接看成两种情况,一种是人行走范围内,猫都闻不到,输出-1,另一种是人行走范围内,猫能闻到,此时我们可以直接看成人一步都不走,猫为起点,人为终点,然后求起点到终点的最短路径,因为此时两者相加最短跟人不动,猫动求得答案等价。

    1.可以用dfs来判断人行走的所有范围,如果某个点,猫能闻到,那么flag为true即可,如果所有能到的点都闻不到就是-1的情况

    2.有解情况,利用bfs来求得最短路即可

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. const int N=1005;
    6. int dist[N][N],n,m,qx,qy,zx,zy,r1,r2;
    7. bool st[N][N];
    8. char a[N][N];//保存地图
    9. int dx[4]={0,0,1,-1};
    10. int dy[4]={1,-1,0,0};
    11. typedef pair<int,int> PII;
    12. void bfs()//求起点到终点的最短路径
    13. {
    14. for(int i=1;i<=n;i++)
    15. {
    16. for(int j=1;j<=m;j++) dist[i][j]=0x3f3f3f3f;
    17. }
    18. queue q;
    19. q.push({qx,qy});
    20. dist[qx][qy]=0;
    21. st[qx][qy]=true;
    22. while(q.size())
    23. {
    24. int x=q.front().first;
    25. int y=q.front().second;
    26. q.pop();
    27. for(int i=0;i<4;i++)
    28. {
    29. int x3=x+dx[i];
    30. int y3=y+dy[i];
    31. if(!(x3>=1&&x3<=n&&y3>=1&&y3<=m)) continue;
    32. if(a[x3][y3]=='*') continue;
    33. if(!st[x3][y3])
    34. {
    35. dist[x3][y3]=dist[x][y]+1;
    36. q.push({x3,y3});
    37. st[x3][y3]=true;
    38. }
    39. }
    40. }
    41. }
    42. bool flag;//记录能否让猫闻到
    43. bool st1[N][N];//记录点是否已经走过
    44. void dfs(int x,int y)//遍历人能到的所有点
    45. {
    46. if((abs(x-zx)+abs(zy-y))>r1||flag||st1[x][y]==true) return;
    47. st1[x][y]=true;
    48. for(int i=0;i<4;i++)
    49. {
    50. int x3=x+dx[i];
    51. int y3=y+dy[i];
    52. if(!(x3>=1&&x3<=n&&y3>=1&&y3<=m)) continue;
    53. if(a[x3][y3]=='*'||st1[x3][y3]) continue;
    54. if((abs(x-qx)+abs(qy-y))<=r2)
    55. {
    56. flag=true;
    57. break;
    58. }
    59. dfs(x3,y3);
    60. }
    61. }
    62. void solve()
    63. {
    64. flag=false;
    65. dfs(zx,zy);
    66. if(!flag)//如果人行走范围都无法让猫闻到
    67. {
    68. printf("-1\n");
    69. return;
    70. }
    71. bfs();
    72. if(dist[zx][zy]==0x3f3f3f3f) printf("-1\n");//表示到不了
    73. else printf("%d\n",dist[zx][zy]);
    74. }
    75. int main()
    76. {
    77. scanf("%d%d%d%d",&n,&m,&r1,&r2);
    78. for(int i=1;i<=n;i++)
    79. {
    80. for(int j=1;j<=m;j++)
    81. {
    82. scanf(" %c",&a[i][j]);
    83. if(a[i][j]=='P') zx=i,zy=j,a[i][j]='.';//记录终点,并变为'.'表示可走
    84. if(a[i][j]=='M') qx=i,qy=j;//记录起点
    85. }
    86. }
    87. solve();
    88. return 0;
    89. }

  • 相关阅读:
    什么是零日攻击?
    下一个行业风口:NFT 数字藏品,是机遇还是泡沫?
    2022牛客多校联赛第九场 题解
    嵌入式函数调用入栈与出栈
    Java可重复注解接口(Repeatable Annotation Interfaces)
    OpenCV学习——绘图函数案例
    3000帧动画图解MySQL为什么需要binlog、redo log和undo log
    【机器学习】梯度下降法与牛顿法【Ⅱ】牛顿法与修正牛顿法
    局部变量,全局变量与内存
    Go Web项目学习之项目结构
  • 原文地址:https://blog.csdn.net/qq_63739337/article/details/127935228