以字元為單位讀取,並依照儲存的狀態進行處理。之所以會使用 isBlank 及 EOF 判斷結束而略過一開始的測資數量,是因為使用了優化過的 getChr(),而它不能與 cin 交替使用。當然,寫完後馬上意識到因為 cin 是在所有的 getChr() 呼叫之前,故就算使用了也沒有影響。
Read the input character-by-character, and process according to the saved state. The reason for using isBlank and EOF for detecting the end of the input instead of just reading the input count on the first line is because an optimized getChr(), which can not be used together. Of course, as soon as I finished this program, I realized that since the cin is called before all the getChr() calls occur, it doesn’t really matter even if I used it.

getChr() 這個函式內部用 fread 存了一個 buffer,加速了字元讀取,但也因此不能與其他的 stdin 函式交替使用。
The function getChr() utilizes an internal buffer in order to accelerate the reading of characters. Because of this, however, it can’t be used together with normal stdin functions.

UVa Link

#include <iostream>
#include <iomanip>
#include <cstdio>

static inline double toMass(char c) {
  switch (c) {
  case 'C':
    return 12.01;
  case 'H':
    return 1.008;
  case 'O':
    return 16.00;
  case 'N':
    return 14.01;
  }
}

int getChr() {
  static char buf[1 << 20], *p = buf, *end = buf;
  if (p == end) {
    if ((end = buf + fread(buf, 1, 1 << 20, stdin)) == buf) return -1;
    p = buf;
  }
  return *p++;
}

int main() {
  std::cin.tie(0);
  std::ios_base::sync_with_stdio(0);
  int add = 0;
  double sum = 0;
  bool isBlank = true;
  char c, lastE = '\0';
  std::cout << std::fixed << std::setprecision(3);
  while (getChr() != '\n');
  while ((c = getChr()) != -1) {
    if (isupper(c)) {
      isBlank = false;
      if (isupper(lastE)) {
        sum += toMass(lastE) * (add ? add : 1);
        add = 0;
      }
      lastE = c;
    } else if (isdigit(c)) {
      isBlank = false;
      add = add * 10 + (c - '0');
    } else if (!isBlank) {
      if (isupper(lastE)) sum += toMass(lastE) * (add ? add : 1);
      std::cout << sum << '\n';
      sum = 0;
      add = 0;
      lastE = '\0';
      isBlank = true;
    }
  }
}