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

YyD
这个OIer很懒,什么也没有没留下搬运于
2025-08-24 22:31:56,当前版本为作者最后更新于2021-07-18 07:37:22,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题目大意:
一个的格子中有若干金币,从左下角出发,每一步可以进行如下操作:
1.向当前方向前进一格;
2.向上移动一步,并调转当前方向。
一开始的方向是向右,到达一个格子时自动收集当前位置的金币,移动过程中不能离开网格图。
问收集完所有金币至少需要多少步?
思路:
贪心。
首先记录下每一行最左/最右的金币的位置,每次贪心地取完这一行的所有金币,
然后判断上一行最左/最右的金币是否在当前方向上,
如果是,就先往前走到那个位置上,然后再上去,否则就直接上去。
代码:
#include<bits/stdc++.h> #define _ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) #define rep(i,l,r) for(int i=l;i<=r;i++) #define lep(i,l,r) for(int i=l;i>=r;i--) #define ll long long #define ull unsigned long long using namespace std; inline int read() { int X=0; bool flag=1; char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();} while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();} if(flag) return X; return ~(X-1); } inline bool isblock(const char &ch) { return ch=='.'||ch=='J'||ch=='Z'; } inline bool getblock() { register char ch; while(!isblock(ch=getchar())); return ch=='J'; } inline int sign(const int &x) { if(x>0) return 1; if(x<0) return -1; return 0; } const int N=1001; int cnt[N],pos[N][2],sum; bool mp[N][N]; int main() { const int n=read(),m=read(); rep(i,1,n) { rep(j,1,m) { mp[i][j]=getblock(); if(mp[i][j]) { if(!pos[i][0]) pos[i][0]=j; pos[i][1]=j; cnt[i]++; sum++; } } } int ans=0; for(register int x=n,y=1,d=1;;x--,d=-d) { if(mp[x][y]) { cnt[x]--; sum--; } while(cnt[x]) { ans++; y+=d; if(mp[x][y]) { cnt[x]--; sum--; } } if(!sum) break; while(pos[x-1][(bool)~d]&&sign(pos[x-1][(bool)~d]-y)==d) { y+=d; ans++; } ans++; } cout<<ans; return 0; }注明:
思路来自 skylee。
- 1
信息
- ID
- 6820
- 时间
- 1000ms
- 内存
- 32MiB
- 难度
- 2
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者