纯粹的模拟题,不需要考虑时间或空间,不过有些细节需要注意:
对于进入循环的情况,即:n enters an inventory loop of length k
k是循环节的长度,比如原串是$0,不断的inventory得到串$1, $2, $3, $4,发现$4==$2,那么k=4-2=2.
所以还需要记录每次操作所得到的结果。
附上AC代码:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;
string inventory(const string &s)
{
int cnt[10] = {};
for (int i = 0; i < (int)s.length(); i++)
cnt[s[i] - '0']++;
string res = "";
for (int i = 0; i <= 9; i++)
{
if (cnt[i] != 0)
{
char tmp[5];
sprintf(tmp, "%d", cnt[i]);
res += tmp;
res += i + '0';
}
}
return res;
}
bool isSelf(const string &s)
{
return s == inventory(s);
}
int main()
{
string s;
while (cin >> s)
{
if (s == "-1")
break;
/* 1: self-inventorying */
if (isSelf(s))
{
cout << s << " is self-inventorying" << endl;
continue;
}
string curS = s;
string history[16];
bool classified = false;
for (int j = 1; j <= 15; j++)
{
curS = inventory(curS);
/* 2: self-inventorying after j steps */
if (isSelf(curS))
{
cout << s << " is self-inventorying after " << j << " steps" << endl;
classified = true;
break;
}
/* 3: loop */
for (int i = 1; i < j; i++)
{
if (history[i] == curS)
{
cout << s << " enters an inventory loop of length " << j - i << endl;
classified = true;
break;
}
}
if (classified) break;
history[j] = curS;
}
/* 4: none of them */
if (!classified)
{
cout << s << " can not be classified after 15 iterations" << endl;
}
}
return 0;
}