POJ 1016 Numbers That Count

Description

"Kronecker's Knumbers" is a little company that manufactures plastic digits for use in signs (theater marquees, gas station price displays, and so on). The owner and sole employee, Klyde Kronecker, keeps track of how many digits of each type he has used by maintaining an inventory book. For instance, if he has just made a sign containing the telephone number "5553141", he'll write down the number "5553141" in one column of his book, and in the next column he'll list how many of each digit he used: two 1s, one 3, one 4, and three 5s. (Digits that don't get used don't appear in the inventory.) He writes the inventory in condensed form, like this: "21131435". 

The other day, Klyde filled an order for the number 31123314 and was amazed to discover that the inventory of this number is the same as the number---it has three 1s, one 2, three 3s, and one 4! He calls this an example of a "self-inventorying number", and now he wants to find out which numbers are self-inventorying, or lead to a self-inventorying number through iterated application of the inventorying operation described below. You have been hired to help him in his investigations. 

Given any non-negative integer n, its inventory is another integer consisting of a concatenation of integers c1 d1 c2 d2 ... ck dk , where each ci and di is an unsigned integer, every ci is positive, the di satisfy 0<=d1<d2<...<dk<=9, and, for each digit d that appears anywhere in n, d equals di for some i and d occurs exactly ci times in the decimal representation of n. For instance, to compute the inventory of 5553141 we set c1 = 2, d1 = 1, c2 = 1, d2 = 3, etc., giving 21131435. The number 1000000000000 has inventory 12011 ("twelve 0s, one 1"). 

An integer n is called self-inventorying if n equals its inventory. It is called self-inventorying after j steps (j>=1) if j is the smallest number such that the value of the j-th iterative application of the inventory function is self-inventorying. For instance, 21221314 is self-inventorying after 2 steps, since the inventory of 21221314 is 31321314, the inventory of 31321314 is 31123314, and 31123314 is self-inventorying. 

Finally, n enters an inventory loop of length k (k>=2) if k is the smallest number such that for some integer j (j>=0), the value of the j-th iterative application of the inventory function is the same as the value of the (j + k)-th iterative application. For instance, 314213241519 enters an inventory loop of length 2, since the inventory of 314213241519 is 412223241519 and the inventory of 412223241519 is 314213241519, the original number (we have j = 0 in this case). 

Write a program that will read a sequence of non-negative integers and, for each input value, state whether it is self-inventorying, self-inventorying after j steps, enters an inventory loop of length k, or has none of these properties after 15 iterative applications of the inventory function.

Input

A sequence of non-negative integers, each having at most 80 digits, followed by the terminating value -1. There are no extra leading zeros.

Output

For each non-negative input value n, output the appropriate choice from among the following messages (where n is the input value, j is a positive integer, and k is a positive integer greater than 1): 
n is self-inventorying 
n is self-inventorying after j steps 
n enters an inventory loop of length k 
n can not be classified after 15 iterations

Sample Input

22 
31123314 
314213241519 
21221314 
111222234459 
-1

Sample Output

22 is self-inventorying 
31123314 is self-inventorying 
314213241519 enters an inventory loop of length 2 
21221314 is self-inventorying after 2 steps 
111222234459 enters an inventory loop of length 2 

Source

 
    题目大致意思:就是给你一组数,然后让你判断它的特性。
    1.判断规则:就是写出给出的数有 n1个n2个2n3个3......为0就不用显示了
       ex:111222333444555777       ------->        313233343537                 //3个1 3个2 3个3 3个4 3个5 (0个6) 3个7
    2.如果经过一轮转换,得到的新序列和初始的序列相同 那么就是 self-inventorying
    3.如果经过k轮的转换后,下一次的转换和上一次的相同,那么就是  self-inventorying after k steps
    3.如果中间某个序列经过 j 次转换后和这个序列相同,那么就是 enters an inventory loop of length j
 
这个题目我WA了几次,主要是因为没有考虑到有可能某个数超过一位数,我如果只是单纯的+'0'就不能达到预期的要求,还有就是题目的意思一开始没有很明白
 
代码如下:
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

string str1, temp;
int MAXN;
int a[100];

int main()        
{
    while (cin >> str1&&str1 != "-1")
    {
        int flag = 0;                      //标记是否已经找到答案
        temp = str1;                       //中间变量
        string str2 = "";                  //保存变化后的序列
        string str3[16];                   //保存每一次变化的序列
        str3[0] = str1;                    //初始第一个序列是原序列
        stringstream ss;                   //用来将int类型转化成string类型
        for (int k = 1; k <= 15; k++)
        {
            memset(a, 0, sizeof(a));
            MAXN = -1;
            for (int i = 0; i<int(temp.size()); i++)
                a[temp[i] - '0']++, MAXN = MAXN > (temp[i] - '0') ? MAXN : (temp[i] - '0');
            for (int i = 0; i <= MAXN; i++)
                if (a[i])
                {
                    ss << a[i];                         //有可能个数会超过一位数,直接加'0'不能达到预期效果
                    str2=str2+ss.str(), str2.push_back(i + '0');
                    ss.str("");                         //清空ss
                } 
            if (str2 == str1&&k == 1)                   //第一轮转换和初始的序列相同
            {
                cout << str1 << " is self-inventorying" << endl;
                flag = 1;
                break;
            }
            if (str2 == temp)                            //经过k轮的转换和上一次的序列相同
            {
                cout << str1 << " is self-inventorying after " << k-1 << " steps" << endl;
                flag = 1;
                break;
            }
            str3[k] = str2;                              //保存转换序列
            temp = str2;
            str2 = "";                                   //清空str2
        }
        if (!flag)
        {
            for (int i = 0; i < 15 && !flag; i++)
                for (int j = i + 1; j <= 15 && !flag; j++)
                    if (str3[i] == str3[j])
                    {
                        cout << str1 << " enters an inventory loop of length " << j - i << endl;
                        flag = 1;
                        break;
                    }
        }
        if (!flag) cout << str1 << " can not be classified after 15 iterations" << endl;
    }
    return 0;
}

 

posted @ 2017-12-08 09:54  念你成疾  阅读(286)  评论(0编辑  收藏  举报