申請SAE

如果您發現本博客的外觀很難看,那是因為部分外觀文件被中國.國家.防火.牆屏.蔽所致!
請翻~牆!

我的Wordpress博客的地址: http://zhuyf.tk/

2012年1月25日 星期三

GDOI2011 樂譜變調 music 解題報告

五、樂譜變調(30分 1-4資料5分,最後一個資料10分)
輸入文件:music.in
輸出文件:music.out
【問題描述】
大家應該聽過很多美妙動聽的歌曲,也曾經在卡拉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

【分析】
看著題目挺花哨,其實很簡單,就是一個模擬,只要讀請題目一般都能滿分。

【我的代碼】

C++语言: Codee#25363
001 /*
002 *Problem: GDOI2011 Music
003 *Author: Yee-fan Zhu
004 *Email: zyfworks@gmail.com
005 */
006 #include <cstdlib>
007 #include <iostream>
008 #include <cstdio>
009 #include <cstring>
010 using namespace std;
011 int N;
012
013 int num[300];
014 int M=0;
015
016 int Hash(char a,char b)
017 {
018     if(a=='C' && b=='0') return 1;
019     if(a=='#' && b=='C') return 2;
020     if(a=='D' && b=='0') return 3;
021     if(a=='#' && b=='D') return 4;
022     if(a=='E' && b=='0') return 5;
023     if(a=='F' && b=='0') return 6;
024     if(a=='#' && b=='F') return 7;
025     if(a=='G' && b=='0') return 8;
026     if(a=='#' && b=='G') return 9;
027     if(a=='A' && b=='0') return 10;
028     if(a=='#' && b=='A') return 11;
029     if(a=='B' && b=='0') return 12;
030     return 0;
031 }
032
033 void print(int a)
034 {
035     if(a==1) printf("C");
036     if(a==2) printf("#C");
037     if(a==3) printf("D");
038     if(a==4) printf("#D");
039     if(a==5) printf("E");
040     if(a==6) printf("F");
041     if(a==7) printf("#F");
042     if(a==8) printf("G");
043     if(a==9) printf("#G");
044     if(a==10) printf("A");
045     if(a==11) printf("#A");
046     if(a==0) printf("B");
047 }
048
049 void init()
050 {   
051     char str[300];
052     scanf("%s\n%d\n",&str,&N);
053     int len=strlen(str);
054     int top=0;
055     int now=2;
056     while(top<len)
057     {
058         char c=str[top];
059         if(c=='#')
060         {
061             int res=(now-1)*12+Hash(c,str[top+1]);
062             num[++M]=res;
063             top+=2;
064             continue;
065         }
066         if(c=='>')
067         {
068             now++;
069             top++;
070             continue;
071         }
072         if(c=='<')
073         {
074             now--;
075             top++;
076             continue;
077         }
078        
079         int res=(now-1)*12+Hash(c,'0');
080         num[++M]=res;
081         top++;
082         continue;
083     }
084 }
085
086 void work()
087 {
088     for (int i=1;i<=M;i++)
089         num[i]+=N;
090     int now=2;
091     int up=25;
092     int down=12;
093     for(int i=1;i<=M;i++)
094     {
095         int tmp=num[i];
096         if(tmp<=down)
097         {
098             now--;
099             down-=12;
100             up-=12;
101             printf("<");
102             print(tmp%12);
103             continue;
104         }
105         if(tmp>=up)
106         {
107             now++;
108             down+=12;
109             up+=12;
110             printf(">");
111             print(tmp%12);
112             continue;
113         }
114         print(tmp%12);
115     }
116 }
117
118 int main()
119 {
120     freopen("music.in","r",stdin);
121     freopen("music.out","w",stdout);
122     init();
123     work();
124     return 0;
125 }

沒有留言:

張貼留言