割草机
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
有一块n*m的地,每块地要么长满杂草(用'W'表示),要么是空地(用'G'表示),现在有一个人站在(1,1),面向(1,m),他可以按如下两种方式移动:
1、向面朝的方向移动一格,耗费1单位时间
2、向下移动一格,并反转面朝的方向(右变左,左变右),耗费1单位时间
现在他想知道清除所有的杂草最少需要多少单位时间(清除完杂草之后不用返回(1,1))
输入描述:
第一行n,m
接下来n行每行一个字符串表示矩阵。
n,m<=150
输出描述:
一行一个整数表示答案。
示例1
输入
4 5
GWGGW
GGWGG
GWGGG
WGGGG
输出
11
示例2
输入
3 3
GWW
WWW
WWG
输出
7
思路:一开始看这道题以为是bfs/dfs那类。。。但是后来又感觉想多了,这个方向是固定的,也就是说必须把这一行的草都割完才能继续,否则不可能向上走,就回不来了。那怎么让它都割完呢?就首先从【1,1】开始,到下一行之前需要保证你下去的位置在能割到所有草的地方。就比如:你现在所在这行只能向右面走,那你需要保证所有的草都在你右边,同理,在你去下一行的时候,你只能向左走,那你下去的位置就要保证所有的草都在你左边才可以。还有一些细节就是如果下边没草就不用往下走了之类的。。。
说起来,这个用bfs/dfs可能也行。。。我这么想有些麻烦了。。。比较笨的方法。。。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
char c[155][155];
int a[155][2];
cin>>n>>m;
for(int i=0;i<n;i++)
{
cin>>c[i];
}
memset(a,-1,sizeof(a));//初始化为-1
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(c[i][j]=='W'&&a[i][0]==-1)
{
a[i][0]=j+1;
a[i][1]=j+1;
}
if(c[i][j]=='W')
{
a[i][1]=j+1;
}
}
}//先将每一行第一个有草的位置和最后一个有草的位置记在一个二维数组中
/*for(int i=0;i<n;i++)
{
printf("%d %d \n",a[i][0],a[i][1]);
}*/
int ans=1,sum=0;
for(int i=0;i<n-1;i++)
{
if(i%2==0)//偶数情况
{
if(a[i][1]!=-1)//这行有草 这行方向固定向右
{
sum+=abs(a[i][1]-ans);
ans=a[i][1];//每次都更新ans的值
//printf("sum=%d ans=%d\n",sum,ans);
if(ans<a[i+1][1])
{//需要和下一行草的位置比较 下一行方向是固定向左的 要保证下一行所有的草都在ans左边
sum+=abs(a[i+1][1]-ans);
ans=a[i+1][1];
//printf("sum=%d ans=%d\n",sum,ans);
}
}
else//没草 也要判断需不需要多走 要保证下一行所有的草都在ans左边
{
if(ans<a[i+1][1]&&a[i+1][0]!=-1)
{
sum+=abs(ans-a[i+1][1]);
ans=a[i+1][1];
//printf("sum=%d ans=%d\n",sum,ans);
}
}
}
else//同偶数情况分析
{
if(a[i][1]!=-1)
{
sum+=abs(ans-a[i][0]);
ans=a[i][0];
//printf("sum=%d ans=%d\n",sum,ans);
if(ans>a[i+1][0]&&a[i+1][0]!=-1)
{
sum+=abs(ans-a[i+1][0]);
ans=a[i+1][0];
//printf("sum=%d ans=%d\n",sum,ans);
}
}
else
{
if(ans>a[i+1][0]&&a[i+1][0]!=-1)
{
sum+=abs(a[i+1][0]-ans);
ans=a[i+1][0];
//printf("sum=%d ans=%d\n",sum,ans);
}
}
}
sum++;
//printf("**sum=%d ans=%d**\n",sum,ans);
}//这个不包括最后一行情况
for(int i=n-1;i>=0;i--)
{
if(a[i][0]==-1)
sum--;
else
break;
}//倒着往上看 如果后面没有草就不必往下走 sum--
if(a[n-1][0]!=-1)
{
if(n%2==1)
{
sum+=abs(a[n-1][1]-ans);
}
else
{
sum+=abs(ans-a[n-1][0]);
}
}//最后一行单独看 分奇偶
cout<<sum<<endl;
return 0;
}