Description
我们的主角——老曹,现在十分忧郁。原因是他在玩一个困难的游戏。
游戏规则如下:
有(N+1)*n/2个圆盘,在平面上摆成了一个变长为N个圆盘的等边三角形。每个圆盘上标有一个小写字母(‘a’_’z’),如下图所示。
对于每个字母,当我们可以由标为这个字母的圆盘为顶点,构成等边三角形时,我们称这个字母为不和谐的。例如途中的a和c。
现在给你N和这个等边三角形上的字母,要求哪些字母是不和谐的。
Input
第一行:一个整数,N(1<=N<=12)
第二行:(N+1)*N/2个小写字母
Output
一行:按字典序输出所有不和谐的字母,如果没有不和谐的字母,则输出“Harmonious”。
Sample Input
样例输入1:
3
aaaaaa
样例输入2:
3
abcdef
Sample Output
样例输出1:
a
样例输出2:
Harmonious
分析:
我们可以以最后一行的第一个圆的圆心作为原点,规定向右、向上为x、y轴的正方向,圆的半径为单位距离,建立笛卡尔(平面直角)坐标系。
然后三重循环枚举同字母的点,判断两两之间的距离是否相等。
关键在于怎样求距离,可以先求出每个点的坐标。
那么,第x行第y个圆的圆心,在坐标系中哪个点呢?
如上图,我们很容易看出A点的横坐标是n+2y-x-2。
至于竖坐标我们把AB分成相等的n-x段,每段根据勾股定理可以得出长度是 3√ ,竖坐标就是 3√ (n-x)。
当我们知道了每个点在坐标系里的位置后,就可以直接求点与点之间的距离,X1
→
X2=
(x1−x2)(x1−x2)+(y1−y2)(y1−y2)−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−√
。
Code:
#include<cstdio>
#include<cstring>
#define fo(i,x,y) for(int i=x;i<=y;i++)
using namespace std;
struct pop
{
int x,y;
}a[26][79];
int n,p,q,b[26];
char c;
int v(int x,int y,int i,int j)
{
return (x-i)*(x-i)+3*(y-j)*(y-j);
}
void init();
void cc();
int main()
{
init();
cc();
}
void init()
{
scanf("%d\n",&n);
fo(i,1,n)
{
fo(j,1,i)
{
scanf("%c",&c);
int u=c-'a';
a[u][++b[u]].x=n+2*j-i-2;
a[u][b[u]].y=n-i;
}
}
}
void cc()
{
fo(i,0,25)
{
p=0;
fo(a1,1,b[i])
{
if(p) break;
fo(a2,a1+1,b[i])
{
if(p) break;
fo(a3,a2+1,b[i])
{
int x,y,z;
x=v(a[i][a1].x,a[i][a1].y,a[i][a2].x,a[i][a2].y);
y=v(a[i][a1].x,a[i][a1].y,a[i][a3].x,a[i][a3].y);
z=v(a[i][a2].x,a[i][a2].y,a[i][a3].x,a[i][a3].y);
if(x==y&&y==x&&x==z)
{
c=i+'a';
printf("%c",c);
p=q=1;
break;
}
}
}
}
}
if(!q) printf("Harmonious");
}