poj1016

来源:互联网 发布:数据挖掘实战微盘 编辑:程序博客网 时间:2024/05/02 04:36

大致题意:

题意不难懂,对于任意的数字串n,都可以压缩存储为

c1 d1 c2 d2 .... ck dk 形式的数字串

而存在一些特别的数字串,其压缩前后的样子是一模一样的

定义这种数字串为self-inventorying

 

当我们把n看成原串,

A为n压缩1次后的数字串,

B为n压缩2次后的数字串(即A压缩1次后的数字串)

....以此类推

K为n压缩k次后的数字串(即K-1压缩k-1次后的数字串)

 

则可以延伸出数字串n的3种属性:

1、  n压缩1次就马上出现self-inventorying特性,即 n n n n n n n .....

2、  n压缩j次后的数字串J出现self-inventorying特性,即 n A B C....H I J J J J J J J

3、  n压缩j次后的数字串J,每再压缩K次,重新出现数字串J,即n A B... J ..K J ..K J..K J

其中K称为循环间隔,K>=2

 

现给定一字符串,输出其属性。  属性1优于属性2,属性2优于属性3



一、问题分析

本文问题分析部分参考http://www.blogjava.net/DreamAngel/articles/294138.html

举一个例子来说明:

一个数5553141:他包含了2个1,1个3,1个4,3个5;
那么和起来写:21131435就是5553141的Inventory 数;
然后题目要求,给出一个数n( 最多80位),他可以被归到如下四类:
1)n is self-inventorying(n用给出那个数代,下同) 
即对给出的数,求出他的Inventory 数,如果是本身,则输出该行;
例如:31123314的Inventory数仍然是31123314,输出: 31123314 is self-inventorying 
2) n is self-inventorying after j steps  
对一个数求他的Inventory 数,然后再对他的Inventory数继续求,如实我们可以得到一个序列:n[0]->n[1]->n[2]…n[j]…. 如此往复,当1<=j<=15时。如果n[j]的Inventory数等于他本身,则输出该行;
例如: 21221314 -> 31321314 -> (31321314),输出: 21221314 is self-inventorying after 2 steps 
3) n enters an inventory loop of length k  
仍然用n的序列说明: n[0]->n[1]->n[2]…n[j]…n[i]…. (0<=j<i<=15),当n[i]的Inventory数(记作n[k]) 等于n[0]…n[i-1]的中n[j]时,那么很显然,再求下会形成一个循环;因此我们要找出是否存在最小(k>=1)使得n序列够成循环,输出这个k; 
例如: 314213241519 --> 412223241519 -->314213241519,对应上述的n[j] --> n[i] -> (n[k])  
4) n can not be classified after 15 iterations 

如果在找出15个数后,没有满足上述的任何一条,那么就输出该行;


二、常用知识点

1、特定跳出的常用形式:
          while(true){
             
             if(   .equals(  )){
                break;
             }
          
          }


2、统计数字串中数各个数字出现的次数
        
          i         0  1  2 ······ 9 
          count[i]
         
        for(i=0;i< n;i++)
            count[s.charAt(i)-'0']++;


3、

import java.util.*;
import java.io.*;


/**
 * 以下对程序可能出现的几种结果进行分析:
 * 
 * 1)n is self-inventorying    第一次处理后与输入一致
 * 2)n is self-inventorying after j steps  再经>1次处理后与输入一致
 * 3)n enters an inventory loop of length k   再经>1次处理后,出现循环
 * 4)n can not be classified after 15 iterations  总共处理15次后仍不满足以上要求
 *
 *  1、1)和2)的相同点在于二者都是连续重复型,差别在于1)是在第一次便开始重复
 *  2、1)、2)、3)都是重复型,但与1)、2)不同的是4)不是连续重复型
 */




public class Main{
    
    public static void main(String rgs[]) throws Exception
    {        
        Scanner cin = new Scanner(new BufferedInputStream(System.in));
        
        /**
         * 特定跳出的常用形式:
         * while(true){
         *    
         *    if(   .equals(  )){
         *       break;
         *    }
         * 
         * }
         */
        while(true){
            String s = cin.next();
            if(s.equals("-1"))
                break;
            String[] t = new String[16];//保存s与15个变换结果
            int i;
            t[0]=s;
            for(i=0;i< 15;i++){
                t[i+1] = change(t[i]);//对当前字符串进行压缩
                int res = Judge (t,i+1); //判断判断字符串的重复情况
                if(res==1 && i==0){
                    System.out.println(s+" is self-inventorying ");
                    break;
                }
                if(res==1){
                    System.out.println(s+" is self-inventorying after "+i+" steps ");
                    break;
                }
                if(res>0){
                    System.out.println(s+" enters an inventory loop of length "+res+" ");
                       break;
                }
            }
            if(i==15)
                System.out.println(s+" can not be classified after 15 iterations ");
        }
    }
    
    /**
     * change(String s) 主要完成对字符串s的压缩,其主要算法如下:
     * 
     * 1)首先设置默认值.  Arrays.fill(count,0);
     * 2)设置统计值.   count[s.charAt(i)-'0']++;
     * 3)输出压缩后的字符串.  t+=String.valueOf(count[i])+String.valueOf(i);
     * 
     * @param s 要进行压缩的字符串
     * @return
     */
    //输出s的Inventory 数,输入5553141则输出21131435 
    public static String change(String s){
        int i,n=s.length();//获得字符串的长度
        
        int[] count=new int[10];//用来存储各个数字出现的次数
        
        String t="";//用来记录压缩后的数字串
        
        //fill(int[] a, int val) .将指定的 int 值分配给指定 int 型数组的每个元素。
        Arrays.fill(count,0);//将所有的次数默认设置为0
        
        
        //统计数字串中数各个数字出现的次数
        /**
         * i         0  1  2 ······ 9 
         * count[i]
         */
        for(i=0;i< n;i++)
            count[s.charAt(i)-'0']++;
        
        //输出压缩后的数字
        for(i=0;i< 10;i++){
            if(count[i]>0)
            //返回inventory数字串的形式
                t+=String.valueOf(count[i])+String.valueOf(i);
        }        
        return t;
    }
    
    /**
     *  Judge(String[] t,int ind) 主要完成将 第ind次变换结果与前面所有结果比较
     * ,主要算法如下:
     * 1)首先判断是否重复.   if(t[ind].equals(t[i]))
     * 2)在1)的基础上判断是否是连续重复.   if(ind==i+1)
     * 
     * @param t  存储有压缩字符串的字符串数组
     * @param ind  要进行判断的字符串的下标
     * @return
     */
    public static int Judge(String[] t,int ind){
        for(int i=0;i< ind;i++){
            if(t[ind].equals(t[i])){//判断是否是重复型
                
            //包括从第一次就self inventory或第n次以后self inventory的情况,不包括循环间隔的情况
            if(ind==i+1)//判断是否是连续型
                    return 1;
                else //不是连续重复型
                    return ind-i;//返回的ind-i就是循环的间隔
            }
        }
        return 0;
    }


}


原创粉丝点击