【問題描述】
大家應該聽過很多美妙動聽的歌曲,也曾經在卡拉OK中唱過不少歌曲。其實,很多歌曲的調子都經過了變調,因為很多歌曲原來的調子一般都偏高,需要把調適當 降低,才適合一般人歌唱。現在請你編程解決這個變調的問題,把一個曲譜從原來的調子基礎上,升高或降低若干個調,變成一個新的曲譜。
【音階】
相信大家都見過電子琴,也聽過電子琴,琴中的每個白色鍵,代表的是簡譜中的1,2,3,4,5,6,7的音階,用字母代表即為 C,D,E,F,G,A,B,見下圖:
此外,上面的黑鍵表示半音,按照上圖,從左邊到右邊的5個黑鍵代表的半音為:#C,#D,#F,#G,#A
由最左邊的音階C數起到第七個音階B,中間的黑鍵和鍵,均處於一個基準八度區域,在B右邊的琴鍵,比原來的音階高一個八度區域,稱為高八度區域; C音階左邊的琴鍵(圖片沒有顯示),比原來的音階低一個八度區域,稱為低八度區域。
【樂譜】
一個歌曲的樂譜,包括音階、節奏、小節線、休止符等元素,這裡為了簡單表示,只保留音階這一元素,節奏、小節線、休止符不在此題目中展現。
樂譜中的每個音階,可以用C,D,E,F,G,A,B,#C,#D,#F,#G,#A 表示。
在樂譜中會牽涉到八度區域的遷移問題,我們使用 “>”、“<” 來變化當前的八度區域。其中“>”表示提高當前八度區域(例如從低八度區域=>基準八度區域),“<”表示降低當前八度區域(例如高八 度區域=>基準八度區域)。樂譜一開始的時候,當前八度區域為基準八度區域。
【樂譜變調】
對一個樂譜,提高或者降低N個半音的操作,成為樂譜變調。
首先,對於一個八度區域中,以下音階均相隔一個半音。
C,#C,D,#D,E,F,#F,G,#G,A,#A,B
然後,B音階比高它一個八度區域的C音階,相隔一個半音
變調就是一個簡單的升降音階的操作,只要數著半音階個數修改音階即可。例如,C音階提高6個半音,數過去就是#F,B音階提高4個音階,則為下一個八度區域的 #D 音階,同理,#F降6個半音階(升-6個半音)則為C。
【輸入格式】
輸入第一行字元串,包含上面的各個音階,以及>/<符號,表示一個樂譜,樂譜字元串長度<=200,沒有空格和其他字元串。
輸入第二行為整數N (-16<=N<=16) ,表示升多少個半音
【輸出格式】
輸出為一行字元串,代表樂譜。
【輸入樣例】
CDEFGAB>C
2
【輸出樣例】
DE#FGAB>#CD
1
const
2 a: array[ 1.. 12] of string
3 =( ' C ', ' #C ', ' D ', ' #D ', ' E ', ' F ', ' #F ', ' G ', ' #G ', ' A ', ' #A ', ' B ');
4 var
5 i,j,k,s,n,prev,PresentStage:integer;
6 st:string;
7 p: array[ 1.. 300] of string;
8 now,stage: array[ 1.. 300] of integer;
9 begin
10 readln(st);
11 readln(n);
12 i:= 1;
13 j:= 0;
14 s:= 1;
15 while i<=length(st) do
16 begin
17 if st[i]= ' < ' then
18 begin
19 s:=s- 1;
20 inc(i);
21 end
22 else
23 if st[i]= ' > ' then
24 begin
25 s:=s+ 1;
26 inc(i);
27 end
28 else
29 if st[i]= ' # ' then
30 begin
31 inc(j);
32 stage[j]:=s;
33 p[j]:=copy(st,i, 2);
34 i:=i+ 2;
35 end
36 else
37 begin
38 inc(j);
39 stage[j]:=s;
40 p[j]:=copy(st,i, 1);
41 i:=i+ 1;
42 end;
43 end;
44 for i:= 1 to j do
45 begin
46 for k:= 1 to 12 do if p[i]=a[k] then prev:=k;
47 now[i]:=prev+n;
48 while now[i]> 12 do
49 begin
50 now[i]:=now[i]- 12;
51 stage[i]:=stage[i]+ 1;
52 end;
53 while now[i]< 1 do
54 begin
55 now[i]:=now[i]+ 12;
56 stage[i]:=stage[i]- 1;
57 end;
58 end;
59 PresentStage:= 1;
60 for i:= 1 to j do
61 begin
62 if stage[i]<PresentStage then
63 begin
64 write( ' < ');
65 dec(PresentStage);
66 end
67 else
68 if stage[i]>PresentStage then
69 begin
70 write( ' > ');
71 inc(PresentStage);
72 end;
73 write(a[now[i]]);
74 end;
75 end.
2 a: array[ 1.. 12] of string
3 =( ' C ', ' #C ', ' D ', ' #D ', ' E ', ' F ', ' #F ', ' G ', ' #G ', ' A ', ' #A ', ' B ');
4 var
5 i,j,k,s,n,prev,PresentStage:integer;
6 st:string;
7 p: array[ 1.. 300] of string;
8 now,stage: array[ 1.. 300] of integer;
9 begin
10 readln(st);
11 readln(n);
12 i:= 1;
13 j:= 0;
14 s:= 1;
15 while i<=length(st) do
16 begin
17 if st[i]= ' < ' then
18 begin
19 s:=s- 1;
20 inc(i);
21 end
22 else
23 if st[i]= ' > ' then
24 begin
25 s:=s+ 1;
26 inc(i);
27 end
28 else
29 if st[i]= ' # ' then
30 begin
31 inc(j);
32 stage[j]:=s;
33 p[j]:=copy(st,i, 2);
34 i:=i+ 2;
35 end
36 else
37 begin
38 inc(j);
39 stage[j]:=s;
40 p[j]:=copy(st,i, 1);
41 i:=i+ 1;
42 end;
43 end;
44 for i:= 1 to j do
45 begin
46 for k:= 1 to 12 do if p[i]=a[k] then prev:=k;
47 now[i]:=prev+n;
48 while now[i]> 12 do
49 begin
50 now[i]:=now[i]- 12;
51 stage[i]:=stage[i]+ 1;
52 end;
53 while now[i]< 1 do
54 begin
55 now[i]:=now[i]+ 12;
56 stage[i]:=stage[i]- 1;
57 end;
58 end;
59 PresentStage:= 1;
60 for i:= 1 to j do
61 begin
62 if stage[i]<PresentStage then
63 begin
64 write( ' < ');
65 dec(PresentStage);
66 end
67 else
68 if stage[i]>PresentStage then
69 begin
70 write( ' > ');
71 inc(PresentStage);
72 end;
73 write(a[now[i]]);
74 end;
75 end.