• 牛客小白月赛60-D-游戏购买!


    题目描述 
    小竹成功从家里逃了出来,他决定去小胖家避一避。但是小胖要求小竹带一个刺激度大于 x 的游戏才能去他家。
    为了防止被妈妈或她的朋友发现,小竹不会在道路上行走,而是在建筑物与建筑物之间穿行。
    街道表现为一个 n×m 的网格,网格上只有两种建筑: 商店和住宅。商店可以通过而住宅无法通过。
    小竹每次从当前所在网格可以行走到上下左右的网格中,但不能移动到网格的边界之外和别人的家中。正式的说,如果他在坐标为 (i,j)的网格里,他可以选择 (i+1,j),(i,j+1),(i−1,j),(i,j−1) , 四个方向行走。
    在位置 (i,j)上的商店有一个刺激度为 wi,j的游戏,小竹可以购买他所经过的商店中的游戏并带走。若wi,j​ 为 −1 则代表这个位置是个住宅,无法通过。

    注意:小胖家以及小竹家均可以被通过。

    假设相邻的建筑物的距离均为 1,小竹想知道带一个刺激度高于 x 的游戏去小胖家需要的最短距离是多少?如果这是不可能实现的,请输出 −1。

     输入描述 
    第一行三个整数 n,m,x(1≤n,m≤2000,1≤x≤109)
    第二行四个整数sx,sy,ex,ey(1≤sx,ex≤n,1≤sy,ey≤m)表示起点与终点的坐标,wsx,sy​,wex,ey​均为0。
    接下来 n 行,每行 m个整数,第 i 行第 j 个整数 wi,j(−1≤wi,j≤109),其中所有商店的wi,j≥1。

    输入:

    1. 3 3 1
    2. 1 1 3 3
    3. 0 1 2
    4. 1 1 -1
    5. 1 1 0

    输出:

    6

    说明:
    小竹从家 (1,1) 出发,需要先前往唯一可以购买刺激度大于 1 游戏的商店 ((1,3) 买到刺激度为 2 的游戏再去小胖家。路线为  (1,1)−>(1,2)−>(1,3)−>(1,2)−>(2,2)−>(3,2)−>(3,3),总距离为6。

    解析:可以说双重最短路,先算出起点到每个商店的最短距离,然后可以将每个商店作为新的起点,注意除了”新起点“之外所有点的距离数组重新初始化为无穷大,然后最短路算出到终点的距离即可。

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const int N=2005;
    7. long long a[N][N];//储存地图
    8. typedef pair<int,int> PII;
    9. vector v;//来用存商店的坐标
    10. long long dist[N][N],n,m,k,qx,qy,zx,zy,dist2[N][N];
    11. //dist1记录原始起点到各点的最短距离,dist2记录新起点到个点的最短距离
    12. void solve1()//算出dist1
    13. {
    14. memset(dist,0x3f,sizeof dist);
    15. dist[qx][qy]=0;
    16. queue q;
    17. q.push({qx,qy});
    18. int d1[4]={0,0,1,-1};
    19. int d2[4]={1,-1,0,0};
    20. while(q.size())
    21. {
    22. int x=q.front().first;
    23. int y=q.front().second;
    24. q.pop();
    25. for(int i=0;i<4;i++)
    26. {
    27. int x1=x+d1[i];
    28. int y1=y+d2[i];
    29. if(!(x1>=1&&x1<=n&&y1>=1&&y1<=m)) continue;
    30. if(a[x1][y1]==-1) continue;
    31. if(dist[x1][y1]>dist[x][y]+1)
    32. {
    33. dist[x1][y1]=dist[x][y]+1;
    34. q.push({x1,y1});
    35. }
    36. }
    37. }
    38. }
    39. void solve2()//算出dist2
    40. {
    41. memset(dist2,0x3f,sizeof dist2);
    42. queue q;
    43. int d1[4]={0,0,1,-1};
    44. int d2[4]={1,-1,0,0};
    45. for(int i=0;isize();i++)
    46. {
    47. int x=v[i].first;
    48. int y=v[i].second;
    49. dist2[x][y]=dist[x][y];//新起点初始距离其实就是原始起点到该点的距离
    50. q.push({x,y});
    51. }
    52. while(q.size())
    53. {
    54. int x=q.front().first;
    55. int y=q.front().second;
    56. q.pop();
    57. for(int i=0;i<4;i++)
    58. {
    59. int x1=x+d1[i];
    60. int y1=y+d2[i];
    61. if(!(x1>=1&&x1<=n&&y1>=1&&y1<=m)) continue;
    62. if(a[x1][y1]==-1) continue;
    63. if(dist2[x1][y1]>dist2[x][y]+1)
    64. {
    65. dist2[x1][y1]=dist2[x][y]+1;
    66. q.push({x1,y1});
    67. }
    68. }
    69. }
    70. if(dist2[zx][zy]>=0x3f3f3f3f) printf("-1\n");
    71. else printf("%lld\n",dist2[zx][zy]);
    72. }
    73. int main()
    74. {
    75. scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&m,&k,&qx,&qy,&zx,&zy);
    76. for(int i=1;i<=n;i++)
    77. {
    78. for(int j=1;j<=m;j++)
    79. {
    80. scanf("%lld",&a[i][j]);
    81. if(a[i][j]>k) v.push_back({i,j});
    82. }
    83. }
    84. solve1();
    85. solve2();
    86. return 0;
    87. }

  • 相关阅读:
    新浪财经行情中心的对象 Market_Center
    shell_42.Linux移动参数
    A-Level商务例题解析及练习Theory of Maslow Theory of Herzberg
    总结嵌入式C语言难点 (1部分) 【结尾有资料】
    vue3基础知识
    linux文件存储之inode,硬链接,软链接详解
    python相关知识的巩固-《python与量化投资从基础到实战》的python基础部分
    使用Node.js构建一个简单的聊天机器人
    姿态分析开源工具箱MMPose使用示例:2d手势估计
    Trie字典树详解
  • 原文地址:https://blog.csdn.net/qq_63739337/article/details/127816226