老曹的忧郁

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= (x1x2)(x1x2)+(y1y2)(y1y2)
这里写图片描述
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");
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值