POJ 1016

Numbers That Count

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 21672   Accepted: 7277

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

East Central North America 1998

 

大致题意:

Kronecker's Knumbers”是一家生产塑料数字的小公司,用于标牌(剧院帐篷,加油站价格显示等)。所有者和唯一员工Klyde Kronecker通过维护库存书记录他所使用的每种类型的数字。例如,如果他刚刚写了一个包含电话号码“5553141”的标志,他会在他的书的一栏中写下“5553141”号,在下一栏中他会列出每个数字中有多少使用:两个1,一个3,一个4和三个5。 (未使用的数字不会出现在清单中。)他以浓缩形式编写库存,如下所示:“21131435”。

前几天,Klyde填写了订单号码31123314,并惊讶地发现这个号码的库存与数字相同---它有三个1,一个2,三个3和一个4!他称这是一个“自我盘点号码”的例子,现在他想知道哪些号码是自我盘点的,或者通过下面描述的盘点操作的迭代应用导致自我盘点号码。你被雇用来帮助他进行调查。

给定任何非负整数n,其库存是另一个整数,由整数c1 d1 c2 d2 ... ck dk的串联组成,其中每个ci和di是无符号整数,每个ci为正,di满足0 <= d1 <d2 <... <dk <= 9,并且,对于出现在n中任何位置的每个数字d,对于某些i,d等于di,并且在n的十进制表示中,d恰好出现ci次。例如,为了计算5553141的库存,我们设置c1 = 2,d1 = 1,c2 = 1,d2 = 3等,给出21131435.数字1000000000000具有库存12011(“十二0,一个1”)。

如果n等于其库存,则整数n称为自库存。如果j是最小数字,则j步骤(j> = 1)之后称为自动清点,使得库存函数的第j次迭代应用的值是自我清点的。例如,21221314在2步后自动盘点,因为21221314的库存为31321314,库存31321314为31123314,而31123314为自库存。

最后,如果k是最小数,则n进入长度为k(k> = 2)的库存循环,使得对于某些整数j(j> = 0),库存函数的第j次迭代应用的值是与第(j + k)次迭代应用的值相同。例如,314213241519进入长度为2的库存循环,因为314213241519的库存为412223241519,而库存412223241519为原始编号314213241519(在这种情况下我们有j = 0)。

编写一个程序,读取一系列非负整数,并为每个输入值说明它是自动库存,j步之后的自动库存,进入长度为k的库存循环,还是没有这些属性库存功能的15次迭代应用。

解题思路:

首先读入字符串

由于只需要压缩十五次就可以判断所有情况,所以设定一个字符二维数组,储存初始字符串和压缩十五次的字符串

1,若第一次压缩后,字符串与原来一致,即符合第一种情况自库存

2,若n(n<=15)次压缩后,压缩之后与压缩之前的字符串一致,则是经过n步子库存

3,若在15次压缩过程中,存在一致的字符串i,j,且其之间的间隔k>1则,称进入长度为k的库存循环

4,否则,是无这些属性的迭代

注意:统计数字个数并组成新字符串时,数字个数可能是两位数,也可能是一位数,要分情况讨论。

          字符数组a[i]循环,一般情况下以下三种无区别 
          while(a[i])
          for(i=0;a[i];i++)
          for(i=0;a[i]!='\0';i++)

代码:

#include <iostream>
#include <cstring>
using namespace std;
/*压缩数字串a,存放到b*/
void change(char *a,char *b)
{
    int num[10]={0};//统计数字出现次数
    for(int i=0;a[i];i++) 
    num[a[i]-'0']++;
    int k=0;
    for(int i=0;i<10;i++)
    {
        if(num[i])
        {
            if(num[i]<10)//数字i出现次数<10,即占1位
            {
                b[k++]=num[i]+'0';
                b[k++]=i+'0';
            }
            else //数字i出现次数>=10,即占2位
            {
                b[k++]=num[i]/10+'0';
                b[k++]=num[i]%10+'0';
                b[k++]=i+'0';
            }
        }
     } 
     b[k]='\0';
     return;
}
int main()
{
    char a[16][85];//n[0]为原串,n[1~15]分别为n连续压缩15次的数字串
    while(cin>>a[0] && a[0][0]!='-')
    {
         int flag1=0,flag2=0,flag3=0;
         //压缩十五次 
         for(int i=1;i<=15;i++)
         change(a[i-1],a[i]);
         //情况一 
         if(!strcmp(a[0],a[1])) 
         {
             flag1=1;
         }
         if(flag1==0)
         { 
         //情况二,且用flag2统计步数 
             for(int i=1;i<15;i++)
             {
                 if(!strcmp(a[i],a[i+1]))
                 {
                     flag2=i;
                      break;
                  } 
            }
            if(!flag2)
            {   
            //情况三,注意压缩步数间隔>=2 
            
                for(int j=0;j<16;j++)
                {
                    for(int k=j+2;k<16;k++) 
                    {
                        if(!strcmp(a[j],a[k]))
                        {
                                flag3=k-j;
                                break;
                        }
                    }
                    if(flag3) //只要有一个出现即可 
                    break;
                }
                
            }
       }
        
        if(flag1==1)
            cout<<a[0]<<" is self-inventorying"<<endl;
        else if(flag2)
            cout<<a[0]<<" is self-inventorying after "<<flag2<<" steps"<<endl;
        else if(flag3)
            cout<<a[0]<<" enters an inventory loop of length "<<flag3<<endl;
        else
            cout<<a[0]<<" can not be classified after 15 iterations"<<endl;
 
    }  
    return 0; 
}

 

 

posted @ 2018-07-26 16:22  fantastic123  阅读(329)  评论(0编辑  收藏  举报