ZJUT1297(循环数)

142857
Time Limit:1000MS  Memory Limit:32768K

Description:

这是一个神奇的数串,它发现于埃及金字塔内,它是一组神奇数字,它证明一星期有7天, 它自我累加一次,就由它的6个数字,依顺序轮值一次,即:142857×1=142857142857×2=285714142857×3=428571142857×4=571428142857×5=714285142857×6=857142现在,在X星球的金字塔内也发现了类似的数字串,这类数字的特征都是有n位长度,当乘以从1到n的数字时,数字串只是数字的位置发生变化,而其他都没变化。那么就要你编个程序判断这个数字是不是这样的循环数字串。

Input:

输入数据是一系列的从2位到60位长度的数串。(注意:数串的前置0不能被移去的,它们被认为数字串的一部分。也就是01是个两位的数串,而1是一位的数串)

Output:

对于每个数串,若其数字是循环的数字,输出Yes,否则输出No。

Sample Input:

142857
142856
142858
01
0588235294117647

Sample Output:

Yes
No
No
No
Yes


本题是一道大数相加和大数相乘的题目,只要根据题目一步步来,首先求出字串与1-n位相乘的结果,最后将此结果和原来的字串进行比较,如果没有其他字符,则输出Yes。
这样子的做法就是略显繁琐,但是条理较为清晰。还有一种方法就是利用循环数的相关性质来进行求解。具体可以看关于循环数在维基百科上的介绍,本人不再赘述。


示例代码:
#include<iostream>
#include<iomanip>
#include<vector>
#include<algorithm>
#include<map>
#include<string>
#include<cmath>
#include<set>


using namespace std;

string bigIntAdd(string a,string b)
{
	int carry = 0;
	string sum,tmp;
	if(a.size() < b.size())
		swap(a,b);
	
	sum = string(a.size(),'0');
	b = string(a.size()-b.size(),'0') + b;

	for(int i = b.size() - 1 ; i>= 0 ; i--)
	{
		sum[i] = (carry + a[i] - 48  + b[i] - 48)%10 + 48;
		carry = (carry + a[i] - 48  + b[i] - 48)/10;
	}

	if(carry != 0)
	{
		tmp = carry + 48 ;
		sum = tmp + sum;
	}

	return sum;
}


string bigIntMul(string a,string b)
{
	string res = "0",tmp,addZero = "",tmp1;
	int carry = 0;
	if(a.size() < b.size())
		swap(a,b);

	
	for(int i = b.size() - 1 ; i >= 0 ; i--)
	{
		tmp = string(a.size(),'0');
		carry = 0;
		for(int j = a.size() - 1 ; j >= 0 ; j--)
		{
			tmp[j] = (carry + (a[j]-48)*(b[i]-48))%10 + 48;
			carry = (carry + (a[j]-48)*(b[i]-48))/10;
		}

		if(carry)
		{
			tmp1 = carry + 48;
			tmp = tmp1 + tmp;
		}

		tmp += addZero;

		addZero += "0";

		res = bigIntAdd(res,tmp);
	}

	return res;


}

string intToString(int n)
{
	string res = "";
	string res1 = "";
	int tmp = n;

	while(tmp != 0)
	{
		res += tmp%10 + 48 ;
		tmp = tmp/10;
	}

	for(int i = res.size()-1 ; i >= 0 ; i--)
		res1 += res[i];


	return res1;
}
int main()
{
	string s,res;
	bool isCorrect;
	int M[10],N[10];
	while(cin>>s )
	{
		isCorrect = true;

		if( s.size() < 2 || s.size() > 60)
			isCorrect = false;

		for(int k = 2 ; k <= s.size(); k++)
		{
			for(int i = 0 ; i < 10 ; i++)
			{
				M[i] = 0;
				N[i] = 0;
			}

			for(int j = 0 ; j < s.size() ; j++)
				M[s[j]-48]++;

			res = bigIntMul(s,intToString(k));


			if(res[0] == '0' && res.size() == s.size()+1)
				res = res.substr(1);


			for(int q = 0 ; q < res.size() ; q++)
				N[res[q]-48]++;


			for(int p = 0 ; p < 10 ; p++)
			{
				if(M[p] != N[p])
				{
					isCorrect = false;
					break;
				}
			}

			if(!isCorrect)
				break;
			
		}

		if(isCorrect)
			cout<<"Yes"<<endl;
		else
			cout<<"No"<<endl;
			

	}
	return 0;
}

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值