/*
* poj 1047 Round and Round We Go
题目大意:
包含n个数字的数,其乘以1到n之间的任意数,所得乘积包含数字与原数相同,且所得数字序列
可由原数循环移位得到,这种数称之为循环数。给定一批数,判断是否是循环数。
解题思路:
1、从1到n乘以原数,判断所得乘积是否是原数数字序列的循环移位所得。
2、因为是从1乘到n,所以可以采用加法替代 -- 涉及大整数的加法的实现
3、判断是否是循环移位所得,可采用后缀数组的方式,判断该序列是否后缀数组的子序列
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
namespace {
using namespace std;
typedef unsigned char UCHAR;
const int N_MAX=60;
UCHAR number[2*N_MAX];
// 大整数加法,返回值为最后一位的进位值
int big_add(UCHAR *pSum, UCHAR *pAugend, UCHAR *pAddend, int n)
{
int s=0, c=0;
for (int i=n-1; i>=0; i--)
{
s = pAugend[i] + pAddend[i] + c;
pSum[i] = s%10;
c = s/10;
}
return c;
}
// 判断是否是循环字串
bool substr(UCHAR *pStr, int n)
{
int i;
for (i=0; i<n; i++)
{
int j=i, k=0; // 后缀数组第i个开始的序列
while (k<n && pStr[k]==number[j])
{
++j;
++k;
}
if (k==n) break; // 是子串
}
return (i<n);
}
}
int main()
{
char str[N_MAX+1];
UCHAR s[N_MAX];
while (EOF != scanf("%s", str))
{
int n=0;
for (int i=0; str[i]!='\0'; i++)
{
++n;
number[i] = str[i]-'0';
s[i] = number[i];
}
for (int i=0; i<n; i++)
{
number[n+i] = number[i]; // 构造后缀数组
}
int i;
for (i=2; i<=n; i++)
{
if (0 != big_add(s, s, number, n))
{
break;
}
if (!substr(s, n))
{
break;
}
}
if (i<=n)
{
printf("%s is not cyclic\n", str);
}
else
{
printf("%s is cyclic\n", str);
}
}
return 0;
}
poj 1047 Round and Round We Go
最新推荐文章于 2019-08-07 16:40:40 发布