- 先讀入測資數,再用
while
迴圈重複讀入每筆測資的音名;會有 getchar()
是因為 gets()
會吃到輸入測資數後的換行
int Case;
scanf("%d", &Case);
getchar();
while(Case--){
char Note[201] = {0};
gets(Note);
...
}
- 宣告兩字元陣列
current
& next
,分別代表當前有按下的手指與下個音要按下的手指,接著 for
迴圈逐字元檢查,觀察各音名與對應的指法後可發現,手指剛好是由多到少且照順序 (因為柱體越長音越低?),因此透過 switch
的特性,故意不要 break
,若是小寫就用 if
把 1 (也就是 [0]) 放開即可
char current[11] = "0000000000";
for(i = 0; i < strlen(Note); i++){
char next[11] = "0000000000";
switch(Note[i]){
case'c':
next[9] = '1';
case'd':
case'D':
next[8] = '1';
case'e':
case'E':
next[7] = '1';
case'f':
case'F':
next[6] = '1';
case'g':
case'G':
next[3] = '1';
case'a':
case'A':
next[2] = '1';
case'b':
case'B':
next[1] = '1';
if(Note[i] >= 'A' && Note[i] <= 'G'){
next[0] = '1';
}
break;
case'C':
next[2] = '1';
}
...
}
- 比較兩字元陣列,計算新按下的有多少,最後更新當前按下的狀態
for(j = 0; j < 10; j++){
if(current[j] == '0' && next[j] == '1'){
count[j]++;
}
}
strcpy(current, next);
- C code ver. 1
#include<stdio.h>
#include<string.h>
int main(){
int Case;
int i, j;
scanf("%d", &Case);
getchar();
while(Case--){
char Note[201] = {0};
char current[11] = "0000000000";
int count[10] = {0};
gets(Note);
for(i = 0; i < strlen(Note); i++){
char next[11] = "0000000000";
switch(Note[i]){
case'c':
next[9] = '1';
case'd':
case'D':
next[8] = '1';
case'e':
case'E':
next[7] = '1';
case'f':
case'F':
next[6] = '1';
case'g':
case'G':
next[3] = '1';
case'a':
case'A':
next[2] = '1';
case'b':
case'B':
next[1] = '1';
if(Note[i] >= 'A' && Note[i] <= 'G'){
next[0] = '1';
}
break;
case'C':
next[2] = '1';
}
for(j = 0; j < 10; j++){
if(current[j] == '0' && next[j] == '1'){
count[j]++;
}
}
strcpy(current, next);
}
printf("%d", count[0]);
for(j = 1; j < 10; j++){
printf(" %d", count[j]);
}
printf("\n");
}
return 0;
}
- 用建表法創建好各音名對應的指法
char fingering[14][12] = { "c0111001111", "d0111001110",
"e0111001100", "f0111001000",
"g0111000000", "a0110000000",
"b0100000000", "C0010000000",
"D1111001110", "E1111001100",
"F1111001000", "G1111000000",
"A1110000000", "B1100000000"};
- 一樣的概念,先
for
迴圈逐字掃,再用內層 for
檢查是哪個音名,用 if
判斷第一個字元 (音名存在 [0]),找到就更新即將按下的指法,第二個 for
迴圈計算新按下的次數
for(i = 0; i < strlen(Note); i++){
char next[12] = {0};
for(j = 0; j < 14; j++){
if(Note[i] == fingering[j][0]){
strcpy(next, fingering[j]);
break;
}
}
for(j = 1; j <= 10; j++){
if(current[j] == '0' && next[j] == '1'){
count[j - 1]++;
}
}
strcpy(current, next);
}
- C code ver. 2
#include<stdio.h>
#include<string.h>
char fingering[14][12] = { "c0111001111", "d0111001110",
"e0111001100", "f0111001000",
"g0111000000", "a0110000000",
"b0100000000", "C0010000000",
"D1111001110", "E1111001100",
"F1111001000", "G1111000000",
"A1110000000", "B1100000000"};
int main(){
int Case;
int i, j;
scanf("%d", &Case);
getchar();
while(Case--){
char Note[201] = {0};
char current[12] = "00000000000";
int count[10] = {0};
gets(Note);
for(i = 0; i < strlen(Note); i++){
char next[12] = {0};
for(j = 0; j < 14; j++){
if(Note[i] == fingering[j][0]){
strcpy(next, fingering[j]);
break;
}
}
for(j = 1; j <= 10; j++){
if(current[j] == '0' && next[j] == '1'){
count[j - 1]++;
}
}
strcpy(current, next);
}
printf("%d", count[0]);
for(j = 1; j < 10; j++){
printf(" %d", count[j]);
}
printf("\n");
}
return 0;
}