传送门:http://poj.org/problem?id=1047
解题思路:
刚看到这题,第一个思路是循环链表(好吧,考研考多了),不想用STL,又懒得自己构造结构体,于是选取了数组。
刚开始,以为是普通乘法运算,写着写着才发现是大数乘法,hiahia,水题中的战斗机...
大数乘法的核心:
int cycNum[100]; // 存放大数的地方,注意一点,数组从低位往高位对应大数低位到高位
// 一个可行方案,将大数读到一个string里面,再对应赋值(!有小陷阱)
int temp, hold = 0; // hold存放进位,temp存放当前位运算后之和
// 从个位起,逐个做乘法运算
for(i = 0; i < n; i++)
{
temp = cycNum[i] * outi + hold;
result[i] = temp % 10;
hold = temp / 10;
}
while(hold > 0)
{
result[i++] = hold % 10;
hold /= 10;
}
下面是源码:
#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
using namespace std;
int cycNum[100], result[100];
int bigMutli(int outi, int n)
{
int temp, hold = 0;
for(int i = 0; i < n; i++)
{
temp = cycNum[i] * outi + hold;
result[i] = temp % 10;
hold = temp / 10;
}
if(hold)
return 0;
return 1;
}
int main()
{
int index[100];
memset(cycNum, -1, sizeof(cycNum));
memset(result, -1, sizeof(result));
memset(index, -1, sizeof(index));
string aNum;
while(cin >> aNum)
{
int n = aNum.length();
for(int i = 0; i < n; i++)
cycNum[n - i - 1] = aNum[i] - '0';
int flag;
for(int i = 1; i <= n; i++)
{
flag = bigMutli(i, n);
if(!flag)
{
cout << aNum << " is not cyclic" << endl;
break;
}
int count = 0, next = result[0];
for(int j = 0; j < n; j++)
if(cycNum[j] == next)
index[count++] = j;
if(0 == count)
{
cout << aNum << " is not cyclic" << endl;
flag = 0;
break;
}
while(count > 0)
{
flag = 1;
for(int j = index[count - 1], k = 0; k < n; k++, j = (j + 1) % n)
if(cycNum[j] != result[k])
{
flag = 0;
break;
}
if(flag)
break;
count--;
}
if(!flag)
{
cout << aNum << " is not cyclic" << endl;
break;
}
}
if(flag)
cout << aNum << " is cyclic" << endl;
}
return 0;
}
最后提下,网上有人采用统计各个数字出现次数来“巧妙”对比是否是循环数,我认为不太妥当,如果出现12345, 54321,这样,按题目说法,这就不是循环数了。
可是循环数恰巧满足该法,囧。。。还是按题目本身来编写代码靠谱。
另外还有一个技巧,就是循环数本身,如果1234是循环数,则1234 X (4 + 1) = 99999,(源数乘以其位数+1的结果必然是位数+1个9),这个方法倒可以有,但太奥数了。