CF115BLawnmower[贪心,模拟]
Posted cgazn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF115BLawnmower[贪心,模拟]相关的知识,希望对你有一定的参考价值。
次优解祭
Cf的数据果然毒瘤, 一百多个点, 卡了我一晚上...
写这道题的一点人生经验 :
- 细节题关键是一开始就要思路清晰, 把情况考虑全, 不能找到一个hack数据改一下,
改着改着代码就成屎了 - 实在是找不到错因就别找了, 直接重构还快得多.
这个题要注意的细节有: - [√] 可能有空行, j最左边的草 = j最右边的草=0, 导致爆炸
- [√] 未考虑中间空多行的情况, 引用了空行(i-1 , i+1等)的草坐标(0), 导致爆炸
- [√] 最后几行都没有草, 还是跳到了最后一行, 导致爆炸
- [√] 没严格执行奇数行只能向右走, 偶数行只能向左走, 导致爆炸
......
打钩表示我踩过这个坑
解决方法: 记录当前人的位置, 发现草再跳, 跳的时候在算距离(曼哈顿距离), 要跳到下一行前分需不需要在上一行跳额外的步数防止逆行两种情况
#include<cstdio>
#define re register
#define in inline
int n,m;
char a[151][151];
int e[151][2];
in int abs(int x)
{
return x>0?x:-x;
}
in int dis(int x1,int y1,int x2,int y2)
{
return abs(x1-x2)+abs(y1-y2);
}
signed main()
{
scanf("%d%d",&n,&m);
for(re int i=1;i<=n;++i)
{
scanf("%s",a[i]+1);
for(re int j=1;j<=m;++j)
{
if(a[i][j]==‘W‘){
if(!e[i][0]) e[i][0]=j;
e[i][1]=j;
}
}
}//e[i][0]第i行最左边草的坐标, e[i][1]最右边的草
int ans=0,nx=1,ny=1;//nx, ny: 当前位置
if(e[1][0]) {ans+=dis(nx,ny,1,e[1][1]);ny=e[1][1];}
for(re int i=1;i<n;++i)
{
if(!e[i+1][0]) continue;
if(i&1){
if(e[i+1][1]>=ny){
ans+=dis(nx,ny,i+1,e[i+1][1]);//防止下一行逆行走的额外步数
nx=i+1,ny=e[i+1][1];
ans+=dis(nx,ny,i+1,e[i+1][0]);
nx=i+1,ny=e[i+1][0];
}
else{
ans+=dis(nx,ny,i+1,e[i+1][0]);
nx=i+1,ny=e[i+1][0];
}
}
else{
if(e[i+1][0]<=ny){
ans+=dis(nx,ny,i+1,e[i+1][0]);//防止下一行逆行走的额外步数
nx=i+1,ny=e[i+1][0];
ans+=dis(nx,ny,i+1,e[i+1][1]);
nx=i+1,ny=e[i+1][1];
}
else{
ans+=dis(nx,ny,i+1,e[i+1][1]);
nx=i+1,ny=e[i+1][1];
}
}
}
printf("%d
",ans);
return 0;
}
以上是关于CF115BLawnmower[贪心,模拟]的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #619 (Div. 2)/CF1301 思维+贪心+模拟+构造+二维ST表
CF 489 C Given Length and Sum of Digits... 贪心