1 条题解
-
0
自动搬运
来自洛谷,原作者为

water_three
**搬运于
2025-08-24 22:37:08,当前版本为作者最后更新于2022-03-28 13:59:51,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
update:
- 由于题意被更改补充,更改了一下做法,如果被卡常可以优化常数。感谢 @星空舞涵 指出错误。
- 又修改了一下小错误。
性质:
首先,通过读题我们可以得出以下性质:无论按怎样的顺序击败敌人,先击败能力值小的敌人的方案总是最优的。
因为在击败敌人后,能力值可能会大于击败前不能击败的敌人。又因为只有当击败敌人后才能通过该格子,所以需要将当前不能击败的记录下来,等到能击败时再搜索一遍。
做法:
我们写一个函数,搜索在起点范围里面能到达并击败的敌人,如果可以直接击败该敌人,直接击败。如果不行,就先存储。
存储完后,在优先队列中从小到大击败,顺便再搜索。如果不能击败此敌人,说明后面更大的敌人也不能击败,直接退出。
最后更新起点坐标。
代码:
#include<bits/stdc++.h> using namespace std; int l,n,m; long long now=1; vector<long long>a[1000001]; int endx,endy; struct shu { int value; int x; int y; bool operator () (const shu &a,const shu &b) const { return a.value>b.value; } }; priority_queue<shu,vector<shu>,shu >q; int tot; int find(int x,int y) { //搜索当前能到达的地方。 if(x<1||x>n||y<1||y>m||a[x][y]==-9||a[x][y]==-1||(endx==x&&endy==y))return 0; if(a[x][y]!=0&&a[x][y]!=-9&&a[x][y]!=-1) { if(now>=a[x][y])now+=a[x][y];//如果能击败,直接击败 else{ q.push({a[x][y],x,y}); a[x][y]=-9; return 0; } } a[x][y]=-9;//避免重复搜索 find(x+1,y); find(x,y+1); find(x-1,y); find(x,y-1); return 0; } int main() { scanf("%d%d%d",&l,&n,&m); int x=1,y=1; while(l--) { if(l==0){ endx=-1,endy=-1; } tot=0; for(int i=1; i<=n; i++) { a[i].clear(); a[i].push_back(0); for(int j=1; j<=m; j++) { int now; cin>>now; a[i].push_back(now); if(a[i][j]==-1) { endx=i,endy=j; } } } find(x,y); while(!q.empty()) { shu top=q.top(); if(top.value<=now) { now+=top.value; a[top.x][top.y]=0; find(top.x,top.y); q.pop(); } else { break; } } priority_queue<shu,vector<shu>,shu >qw; q=qw;//注意清空队列 x=endx,y=endy;//更新起点 } cout<<now<<endl; }
- 1
信息
- ID
- 7543
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者