『题解』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;
}
posted @ 2022-01-21 21:30  仙山有茗  阅读(36)  评论(0编辑  收藏  举报