南阳理工OJ 52 无聊的小明 找循环节

/*
如果是循环的,那么往后乘,必然会有和第一个相等,
如果不是循环的,那么往后乘,必然会有一个和第一个后面的相等,
而不是和第一个相等,所以先记录第一个,然后每乘一个都要看看有没有
和前面相等的出现,并且num++,直到出现为止。
如果出现了而不是和第一个相等,就输出-1
如果和第一个相等就输出num。
有一个问题:
怎么才能知道一个数出现过两次?
(这里用到了map容器,可以很方便的知道一个数是否出现过,
  看看下面代码就知道容器的用法啦!)
*/
#include<iostream>
#include<map>
using namespace std;
map<int,bool>m;//定义一个空容器
int main()
{
	int T,n,k,term,f,num,i;
	cin>>T;
	while(T--)
	{
		cin>>n>>k;
		for(i=0,term=1;i<k;i++)term*=10;
		k=term;//k为10的k次方
		n%=k;//为了防止溢出,取余数
		f=term=n;//f标记n的一次放
		num=0;
		while(m.find(term)==m.end())//如果term没有出现过
		{
			num++;//标记循环节数
			m[term]=true;//标记term为出现过
			term=(int)(((long long)term*n)%k);//算出下一个term(注意防止溢出)
		}
		if(term!=f)cout<<"-1\n";//如果出现循环并且不是第一个,就输出-1
		else cout<<num<<endl;//否则输出num
		m.clear();//注意别忘记清空容器哦!
	}
	return(0);
}

 

你可能感兴趣的:(循环)