题目:https://ac.nowcoder.com/acm/contest/61504/A
有一块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
总结:
思路:储存每一行最左边和最右边需要遍历的位置
对 列数 分奇偶判断是从左到右还是从右到左
代码献上(图论)
#include<bits/stdc++.h>
using namespace std;
int q[200][3];
char arr[200];
string str;
int n, m, last, end1, res, start;
int main()
{
cin >> n >> m;
for (int i = 1; i <= n + 1; i++)
{
q[i][1] = 200; //存最大
q[i][2] = -100; //存最小
}
for (int i = 1; i <= n; i++)
{
memset(arr, '0', sizeof(arr)); //初始化
cin>> arr + 1;
//cin>>str;
for (int j = 1; j <= m; j++)
{
if (arr[j] == 'W')
{
if (j < q[i][1])
{
q[i][1] = j; //存最小位置
}
if (j > q[i][2])
{
q[i][2] = j; //存最大位置
}
last = i;
}
}
}
start = 1; //头指针
for (int i = 1; i <= last; i++)
{
if (i % 2) //奇数从左到右
{
end1 = max(q[i][2], q[i + 1][2]);
if (end1 - start > 0)
{
res += (end1 - start); //位置储存
start = end1;
}
}
else //偶数从右到左
{
end1 = min(q[i][1], q[i + 1][1]);
if ((start - end1) > 0)
{
res += (start - end1); //位置储存
start = end1;
}
}
}
cout << res + last - 1 << endl; //输出最小移动次数
return 0;
}