首页 > 基础算法 > 枚举 > hdu 1479 Numbers That Count-字符串-[解题报告]
2013
12-11

hdu 1479 Numbers That Count-字符串-[解题报告]

Numbers That Count

问题描述 :

“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 c1d1c2d2…ckdk, 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.

This problem contains multiple test cases!

The first line of a multiple input is an integer N, then a blank line followed by N input blocks. Each input block is in the format indicated in the problem description. There is a blank line between input blocks.

The output format consists of N output blocks. There is a blank line between output blocks.

输入:

The input file contains multilple cases,and each having at most 80 digits, followed by the terminating value -1. There are no extra leading zeros.

输出:

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

样例输入:

22
31123314
314213241519
21221314
111222234459
-1

样例输出:

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

//Memory Time 
 //232K   32MS 
 
 #include<iostream>
 #include<string>
 using namespace std;
 
 /*压缩数字串n,存放到t*/
 void R(char* n,char* t)
 {
     int i,j;
     int time[10]={0};  //记录n中各个数字出现的次数
     for(i=0;n[i];i++)
         time[ n[i]-'0' ]++;
 
     for(i=0,j=0;i<10;i++)
     {
         if(time[i])
         {
             if(time[i]<10)  //数字i出现次数<10,即占1位
             {
                 t[j++]=time[i]+'0';
                 t[j++]=i+'0';
             }
             else    //数字i出现次数>=10,即占2位
             {
                 t[j++]=time[i]/10+'0';
                 t[j++]=time[i]%10+'0';
                 t[j++]=i+'0';
             }
         }
     }
     t[j]='\0';
 
     return;
 }
 
 int main(int i,int j)
 {
     char n[16][85];    //n[0]为原串,n[1~15]分别为n连续压缩15次的数字串
 
     while(cin>>n[0] && n[0][0]!='-')
     {
         bool flag1=false;    //属性1,n is self-inventorying
         int flag2=0;         //属性2,n is self-inventorying after j steps,顺便记录j
         int flag3=0;         //属性3,n is enters an inventory loop of length k,顺便记录k
 
         for(i=1;i<=15;i++)
             R(n[i-1],n[i]);
 
         if(!strcmp(n[0],n[1]))  //属性1,n压缩1次就是其本身
             flag1=true;
 
         if(!flag1)
         {
             for(j=1;j<15;j++)
                 if(!strcmp(n[j],n[j+1]))  //属性2, n压缩j次后的数字串n[j]具有属性1
                 {
                     flag2=j;
                     break;
                 }
 
             if(!flag2)
             {
                 for(j=1;j<=15;j++)  //属性3,两两枚举各次压缩的数字串,注意循环间隔>=2
                 {
                     for(i=0;i<=j-2;i++)
                     {
                         if(!strcmp(n[j],n[i]))
                         {
                             flag3=j-i;
                             break;
                         }
                     }
                     if(flag3)
                         break;
                 }
             }
         }
 
         if(flag1)
             cout<<n[0]<<" is self-inventorying"<<endl;
         else if(flag2)
             cout<<n[0]<<" is self-inventorying after "<<flag2<<" steps"<<endl;
         else if(flag3)
             cout<<n[0]<<" enters an inventory loop of length "<<flag3<<endl;
         else
             cout<<n[0]<<" can not be classified after 15 iterations"<<endl;
     }
     return 0;
 }

解题转自:http://www.cnblogs.com/lyy289065406/archive/2011/08/09/2132774.html


  1. #include <cstdio>

    int main() {
    //answer must be odd
    int n, u, d;
    while(scanf("%d%d%d",&n,&u,&d)==3 && n>0) {
    if(n<=u) { puts("1"); continue; }
    n-=u; u-=d; n+=u-1; n/=u;
    n<<=1, ++n;
    printf("%dn",n);
    }
    return 0;
    }

  2. 第二种想法,我想来好久,为啥需要一个newhead,发现是把最后一个节点一直返回到嘴上面这层函数。厉害,这道题之前没样子想过。