《黑书》数据结构:poj1879小球钟——时间与运动

黑书P38,这是黑书给出的思路:《黑书》数据结构:poj1879小球钟——时间与运动
我就是按照这个思路来编写的,不过有几个需要注意的地方,导致我wa了几次。

先说说我自己编完这道题目的想法吧:看完这道题目,我的想法是按照一分钟一分钟去模拟,再判断哪天会是全部相等,但无疑,我那种想法必定超时。然后看了黑书的思路,
发现原来有周期的是可以这样做的......学到了,以后对于类似的题目,可以思考这么做,求出单个的周期,再求它们的最小公倍数......

注意:可以这样做的条件,是必须要是初始和末尾状态相同的,就这道题目来说,小球是要全部在底层的队列里面才可以这样思考的,那么,当不是所有的小球都在底层的时候,我们必须要使它们到底层的时候,才能这样操作的.......如此来说,我们可以以半天也就是12个小时为一次置换也是可以的......
好吧,废话不多说了,编这个代码要注意几点,
1、对于怎么建立起置换的,这个我是用递归实现的,这也是我代码喂猫跑这么长时间的原因!
2、在模拟完所有情况的时候,在将要建立置换前,先要考虑有的小球,在不用置换就已经是原来的位置了......就是说,位置不会改的点......
3、注意,已经有了周期的点,不需要再改变.....也就是说只要第一个周期,这个一开始我考虑了,后来写的时候忘了........

#include<iostream>

#include<queue>

#include<stack>

#include<stdio.h>

#include<string.h>

using namespace std;

int a[7005],vist[7005],flg;

int gcd(int m,int n)

{

	if(m<n)

	{

		int tmp=m;

		m=n;

		n=tmp;

	}

	int r;

	while(m%n!=0)

	{

		r=m%n;

		m=n;

		n=r;

	}

	return n;

}

void digui(int b[],int c[],int d[],int num,int n)

{

	if(b[flg]==num)

	{

		d[flg]=c[num];

		vist[flg]=1;

		return;

	}

	int i=1;

	for(;i<=n;i++)

	if(b[i]==num)

	break;

	digui(b,c,d,i,n);

	d[i]=c[num];

	vist[i]=1;

}

int main()

{

	int n;

	while(scanf("%d",&n)>0&&n)

	{

		queue<int>Q;

		stack<int>s1;

		stack<int>s2;

		stack<int>s3;

		for(int i=1;i<=n;i++)

		{

			a[i]=i;

			Q.push(a[i]);

		}

		int i=1;

		while(1)

		{

			if(i>1440)

			break;

			int tmp=Q.front();

			Q.pop();

			if(i%5!=0)

			s1.push(tmp);

			else

			{

				s1.push(tmp);

				int tmp1=s1.top();

				s1.pop();

				s2.push(tmp1);

				while(!s1.empty())

				{

					int tmp2=s1.top();

					s1.pop();

					Q.push(tmp2);

				}

			}

			if(i%60==0)

			{

				int tmp1=s2.top();

				s2.pop();

				s3.push(tmp1);

				while(!s2.empty())

				{

					int tmp2=s2.top();

					s2.pop();

					Q.push(tmp2);

				}

			}

			if(i%720==0)

			{

				int tmp1=s3.top();

				s3.pop();

				while(!s3.empty())

				{

					int tmp2=s3.top();

					s3.pop();

					Q.push(tmp2);

				}

				Q.push(tmp1);

			}

			i++;

		}

		int b[7005],c[7005],d[7005];

		int j=1;

		while(!Q.empty())

		{

			int tmp1=Q.front();

			Q.pop();

			c[j]=b[j]=tmp1;

			j++;

		}

		

		memset(a,-1,sizeof(a));

		for(i=1;i<=n;i++)

		if(b[i]==i)

		a[i]=1;

		int w=1;

		/*

		for(i=1;i<=n;i++)

		printf("%d ",c[i]);

		printf("\n");

		i=1;

		memset(vist,0,sizeof(vist));

		while(i<=n)

		{

			if(!vist[i])

			{

				flg=i;

				digui(b,c,d,i,n);

			}

			i++;

		}

		for(i=1;i<=n;i++)

		printf("%d ",d[i]);

		printf("\n");

		*/

		while(1)

		{

			for(i=1;i<=n;i++)

			if(a[i]==-1)

			break;

			if(i>n)

			break;

			i=1;

			memset(vist,0,sizeof(vist));

			while(i<=n)

			{

				if(!vist[i])

				{

					flg=i;

					digui(b,c,d,i,n);

				}

				i++;

			}

			w++;

			j=1;

			for(;j<=n;j++)

			{

				c[j]=d[j];

				if(a[j]==-1&&d[j]==j)

				{

					a[j]=w;

				}

			}

		}

		int tmp=a[1];

		for(i=2;i<=n;i++)

		{

			tmp=tmp*a[i]/gcd(tmp,a[i]);

		}

		printf("%d balls cycle after %d days.\n",n,tmp);

	}

	return 0;

}

 

你可能感兴趣的:(数据结构)