zoj1504Slots of Fun

刚开始看这道题目的时候就感觉没有什么特别的方法,就把所有的都枚举一遍,算了算时间,字符串最长也就是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;

}

你可能感兴趣的:(ZOJ)