刚开始看这道题目的时候就感觉没有什么特别的方法,就把所有的都枚举一遍,算了算时间,字符串最长也就是78,相对来说比较小,感觉不会超时的,
但是昨天写的时候感觉思路不是很清楚,就没再接着写,今天又顺着昨天的思路理了理,感觉还可以,就敲了一下,没想到实例都通过了,交了AC。。
我的思路就是把所有的a~z出现的次数以及出现的位置都例举出来, 把他们的位置用坐标表示,第一行第一个数是(0,0),第二行从左到右为(-1,-sqrt(3)),(1,-sqrt(3));
然后依次推出所有字母的坐标。。
最后对于每个字符出现次数,任意枚举三个位置,看看这三点构成的是否是一个等边三角形。。。
代码如下:
# include<stdio.h> # include<string.h> # include<math.h> # define PI sqrt(3) struct node{ int x; double y; }s[100];/*用来存每一个字母的坐标*/ int visit[30][100],sum[30]; /*visit数组用来存每一个字母出现的位置*/ /*sum数组用来存每一个字母出现的次数*/ double dist(int i,int j,int k) { int ans1,ans2; ans1=visit[i][j]; ans2=visit[i][k]; return (s[ans1].x - s[ans2].x)*(s[ans1].x - s[ans2].x) + (s[ans1].y - s[ans2].y)*(s[ans1].y - s[ans2].y); /*为了提高精度,这个地方直接返回平方的值*/ } int main() { int i,j,n,num,k,h,flag,ans,count; char str[100]; while(scanf("%d",&n)!=EOF &&n) { getchar(); gets(str); memset(sum,0,sizeof(sum)); count=0; ans=0; for(i=0;i<n;i++) { num=-i; for(j=0;j<=i;j++) { s[ans].x= num; s[ans].y= -1*i*PI; flag=str[ans]-'a'; sum[flag]++; visit[flag][sum[flag]]=ans; ans++; num+=2; } } for(i=0;i<=25;i++) { if(sum[i]>=3)/*如果该字母出现的次数不小于3次,则进行下面的操作*/ { flag=0; for(j=1;j<=sum[i];j++) { for(k=j+1;k<=sum[i];k++) { for(h=k+1;h<=sum[i];h++) {/*任意枚举三个位置*/ if(fabs(dist(i,j,k)-dist(i,j,h))<=1e-10 && fabs(dist(i,j,k)-dist(i,k,h))<=1e-10) { /*double型的精确6位,平方之后相当于精确了12位,就可以让返回的结果与1e-10进行比较*/ printf("%c",i+'a'); count++; flag=1; break; } } if(flag==1) break; } if(flag==1) break; } } } if(count==0) printf("LOOOOOOOOSER!");/*如果没有等边的三角形*/ printf("\n"); } return 0; }