『题解』UVa online judge UVA1641 ASCII面积 ASCII Area
题目大意
有多组数据,对于每组数据,给定一个字符矩阵的长和宽 \(n,m\),接下来 \(n\) 行,每行 \(m\) 个字符。
对于每个字符:
- 如果为
/
或\
,则为一半被覆盖,/
表示上升,\
表示下降。 - 如果为
.
,则是完全被覆盖或完全不覆盖。完全覆盖情况就是这个字符前方除了.
之外,第一个遇见的字符为/
。否则,就是完全不覆盖
思路
我们可以将每行可以抽象成一个二维的土堆,/
和 \
表示坡。.
则是平面,高低看前面的 /
和 \
字符。
朴素做法很简单,每行作单独操作,设置一个 bool
类型的变量 flag
,表示是否凸起,也就是完全覆盖。这样处理每个字符:
- 如果字符为
/
或\
:将答案加上 \(0.5\),并改变flag
的状态。 - 如果字符为
.
:如果flag
为 \(1\) 也就是凸起,就将答案加上 \(1\);否则,直接跳过。
但是,我可能有强迫症,所以不想使用 double
的类型,所以记录答案的变量 ans
类型为 int
加 \(0.5\) 时直接加 \(1\),加 \(1\) 时直接加 \(2\),最后输出时除以 \(2\) 即可。
代码
#include <iostream>
using namespace std;
int n,m,ans;
char c; // 不需要数组,一个字符就够了
bool flag; // 记录字符为'.'时是否完全覆盖,遇到'/'或'\'就改变
int main(){
while(cin >> n >> m){ // 用于处理多组数据
for(int i=1; i<=n; i++,flag=0){ // 记得每次将flag置0
for(int j=1; j<=m; j++){
cin >> c;
// ans是要直接加两倍,为了不用浮点数,最后再除以2就行了
if(c=='/' || c=='\\'){ // 上升或下降(凸出或凹下)
ans++; // 加上1,也就是0.5
flag=!flag; // 改变状态
}else if(flag){ // 不是'/'也不是'\'则必定是'.',那么在完全覆盖情况,就加
ans+=2; // 加上2,也就是1
}
}
}
cout << ans/2 << endl;
ans=0; // 记得置0
}
return 0;
}