開啟章節選單

10415 Eb Alto Saxophone Player

題目連結

題目敘述

你擁有一支 降 E 調中音薩克斯風(Eb Alto Saxophone),在演奏某些樂曲時,你發現手指動得非常頻繁,於是你對「每根手指在整首樂曲中實際按下幾次按鍵」產生了興趣

音符說明:

  • 樂曲中的音符來自兩個八度,共 14 種音符:
    • 第一個八度: c d e f g a b (小寫)
    • 第二個八度: C D E F G A B (大寫)
音符使用手指編號
c2~4, 7~10
d2~4, 7~9
e2~4, 7, 8
f2~4, 7
g2~4
a2, 3
b2
C3
D1~4, 7~9
E1~4, 7, 8
F1~4, 7
G1~4
A1~3
B1, 2

輸入說明

第一行輸入一個整數 t( 1 ≤ t ≤ 1000 ),代表總共有幾筆測資 (幾首樂曲)
接下來 t 行,每行是一首樂曲的音符序列 (可能為空)
音符字元只可能是 {c,d,e,f,g,a,b,C,D,E,F,G,A,B}
每首樂曲最多 200 個音符

輸出說明

對於每一筆測資,請輸出 10 個整數,代表每一根手指在這首樂曲中實際按下去的次數
按照手指編號 1 到 10 的順序輸出,中間以 單一空格分隔

解題思路

  1. 建立音符與手指對應表(音符 -> 手指編號)
  2. 模擬每一筆旋律的手指按壓過程
    • 「按壓」的條件:
      • 某手指在 當前音符要使用,但上一個音符沒使用到 ⇒ 要算一次按下
      • 第一個音符中用到的手指一律都算一次按下

程式碼

#include <iostream>
#include <sstream>
#include <unordered_map>
#include <vector>
using namespace std;

int main() {
  unordered_map<char, vector<int>> mp;
  mp['c'] = {2, 3, 4, 7, 8, 9, 10};
  mp['d'] = {2, 3, 4, 7, 8, 9};
  mp['e'] = {2, 3, 4, 7, 8};
  mp['f'] = {2, 3, 4, 7};
  mp['g'] = {2, 3, 4};
  mp['a'] = {2, 3};
  mp['b'] = {2};

  mp['C'] = {3};
  mp['D'] = {1, 2, 3, 4, 7, 8, 9};
  mp['E'] = {1, 2, 3, 4, 7, 8};
  mp['F'] = {1, 2, 3, 4, 7};
  mp['G'] = {1, 2, 3, 4};
  mp['A'] = {1, 2, 3};
  mp['B'] = {1, 2};

  string T;
  int t;
  getline(cin, T);
  stringstream ss;
  ss << T;
  ss >> t;

  for (int i = 0; i < t; i++) {
    vector<int> cnt(10 + 1, 0);
    vector<bool> press(10 + 1);
    string s;
    getline(cin, s);
    for (auto ch : s) {
      for (auto finger : mp[ch]) {
        if (!press[finger]) {
          press[finger] = true;
          cnt[finger] += 1;
        } else {
          continue;
        }
      }
      for (int j = 1; j <= 10; j++) {
        press[j] = false;
        for (auto finger : mp[ch]) {
          if (j == finger) {
            press[j] = true;
            break;
          }
        }
      }
    }
    for (int k = 1; k <= 10; k++) {
      if (k > 1) cout << " ";
      cout << cnt[k];
    }
    cout << endl;
  }
  return 0;
}