zoj 1274 Getting Chorded(啊,模拟题 = =)

党把 这题过了,然后我就看看吧。

 

这题就90多人过 = =。。。大家看到这种类型的都不想看题吧。。。无语。。

 

这题蛮简单的,给你三个钢琴键的音符,问你是否能演奏出和弦。

 

中间描述有点纠结,大意是这样的,12个键循环,分别是

 

A A# B C C# D D# E F F# G G# | A A# B C ...循环下去。。

 

如果是某个字符的大调,比如C大调,那么肯定是由 C  E  F#构成,C和E差三个音,E 和 F 差俩。

 

小调的话,比如C小调,是由C D# F,C和D#差俩,D#和E差仨,都是按这种排法。如果超过12个的话,往下面循环的键里找。

 

我开始的做法是,找到每个键对应的位置,把每个大调小调用一个数存下,我是用每个位置的平方和存的。

 

WA了,因为三个数的平方和,这个数可能有好几组解= =。。好吧,我又用立方和,保证只有一组解。

 

这个输入忽略大小写了,如果是小写需要变一下,而且A#有Bb等写法,注意变一下。

 

写了个求立方和的程序,使工作量减小了点。。。

 

 

 

P.S.党说他的做法是,算2的多少次方,然后累和。他这个是唯一的,这相当于2进制表示呀~好方法~肯定不会有多租解。

 

 

 

#include <stdio.h> #include <stdlib.h> #include <iostream> #include <string.h> using namespace std; char str[13][5] = {"","A","A#","B","C","C#","D","D#","E","F","F#","G","G#"}; int Mar[13] = {0,638,953,1370,1907,2582,1217,1682,2267,794,1133,1574,2135}; int Min[13] = {0,577,862,1243,1738,2365,946,1351,1870,2521,1126,1555,2098}; char name[10]; int process() { int len ,i; len = strlen(name); name[0] = toupper(name[0]); if( len == 2 && name[1] == 'b' ) { if( name[0] == 'A' ) name[0] = 'G'; else name[0]--; name[1] = '#'; } for(i=1; i<=12; i++) if( strcmp(str[i],name) == 0 ) break; return i; } int main() { char tmp[10][10]; int x,ans,flag,cou,i; while( scanf("%s",name) != EOF ) { ans = flag = cou = 0; strcpy(tmp[cou++],name); x = process(); ans += x*x*x; scanf("%s",name); strcpy(tmp[cou++],name); x = process(); ans += x*x*x; scanf("%s",name); strcpy(tmp[cou++],name); x = process(); ans += x*x*x; for(i=1; i<=12; i++) if( ans == Mar[i] ) { flag = 1; break; } if( flag == 1 ) { printf("%s %s %s is a %s Major chord./n",tmp[0],tmp[1],tmp[2],str[i]); continue; } for(i=1; i<=12; i++) if( ans == Min[i] ) { flag = 1; break; } if( flag == 1 ) { printf("%s %s %s is a %s Minor chord./n",tmp[0],tmp[1],tmp[2],str[i]); continue; } printf("%s %s %s is unrecognized./n",tmp[0],tmp[1],tmp[2]); } return 0; }  

你可能感兴趣的:(zoj 1274 Getting Chorded(啊,模拟题 = =))