Armin
迷茫的话 TRY AGAIN 多少次都能重新再来

卡拉兹(Callatz)猜想已经在1001中给出了描述。在这个题目里,情况稍微有些复杂。

当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数。例如对n=3进行验证的时候,我们需要计算3、5、8、4、 2、1,则当我们对n=5、8、4、2进行验证的时候,就可以直接判定卡拉兹猜想的真伪,而不需要重复计算,因为这4个数已经在验证3的时候遇到过了,我 们称5、8、4、2是被3“覆盖”的数。我们称一个数列中的某个数n为“关键数”,如果n不能被数列中的其他数字所覆盖。

现在给定一系列待验证的数字,我们只需要验证其中的几个关键数,就可以不必再重复验证余下的数字。你的任务就是找出这些关键数字,并按从大到小的顺序输出它们。

输入格式:每个测试输入包含1个测试用例,第1行给出一个正整数K(<100),第2行给出K个互不相同的待验证的正整数n(1<n<=100)的值,数字间用空格隔开。

输出格式:每个测试用例的输出占一行,按从大到小的顺序输出关键数字。数字间用1个空格隔开,但一行中最后一个数字后没有空格。

输入样例:
6
3 5 6 7 8 11
输出样例:
7 6

================================================================
IDEA:
首先,在接收数列的时候,共分成两层循环:
外循环: 负责接收 每次 输入的数列中的数据 将其存入 数组 K[] 中,
  内循环: 负责将每次 接收到的数据 进行 卡拉兹猜想 操作,将 接收的数据进行拆分后 存放到: COVER[cov_len++]中,
  
所以在 外循环结束 整个数列的接收操作之后, COVER中已经将 接收到全部的数列的 所有 覆盖数 (K[i] 的 覆盖数不包括 K[i]本身)存放到数组COVER中了。

因为,在题目中 并没有表示 输入样例一定是按照 非递减 的顺序 输入的,
并且 在输出样例中 要求的是 数据时按照 非递增的 方式输出的,

所以,在接下来的步骤中,对 数列K[0...k-1] 进行一个排序是很有必要的。

排序K[0..k-1]


然后,再次执行一个双层循环
外循环: 一次遍历 K[0..k-1] 中的每一个数字
{
   { 内循环: 获取外循环的 第 i 个 K 元素 K[i] ,对COVER 进行一个j->[0..cov_len -1] 的遍历
        if K[i] == COVER[j] break 当前循环: 说明 数列 K[i] 在 COVER中是存在的,即 K[i] 是被覆盖的
   }
   if j == cov_len - 1 : 说明 当前K[i] 在 COVER中 [0..cov_len]是不存在的,故 K[i]是我们要找的关键字
   {
     但是,在这里并不要急着输出,因为,我们不知道K[i] 是否是 关键字的最后一个,即 K[i] 数列中的最后一个 元素 并不一定是 关键字的最后一个
     而且,在题目中明确要求,如果是最后一个关键字的话,输出的时候是不需要加空格的,
     所以,没法保证空格的添加满足题意, 所以先将其 存放起来:
    out [out_len++] = K[i]
    }
}

输出关键字,数组:

for ( 0.. out_len-1 )
printf(out[i])
if ( i != out_len -1 )
printf (" ")

另外,在数组 长度的选取方面也是需要注意的, 通过K 的值可知道 个数[1,100] , 通过n [1,100] 可以知道,在 1到100 之间最多的 需要几次 猜想。
而且从 前一个程序中 可以知道, 在对 1 到 100 数字之间,最多的一个猜想次数是 97 :75 次, 所以覆盖数目最多可以 100*100 =10000 次,
根据这个,可以设定 COVER 的数组的数目。
==========================================================================
SRC:
#include <stdio.h>

int main ()
{
  int X ;
  int COVER[10000], cov_len ;
  int K[100] ,tmp ;
  int loop , i,j ;
  int out[100] , out_len ;

  scanf ("%d", &loop ) ;
  
  cov_len =  0 ;

  for ( i = 0 ; i < loop ; i++ )
  {
    
    scanf("%d" , &X ) ;

    K[i] = X ;

    while(X!=1)
    {
      if ( X%2)
      {
        X = (3*X+1)/2 ;
        COVER[cov_len++] = X ;
      }
      else
      {
        X = X/2 ;
        COVER[cov_len++] = X ;
      }
    }
  }

  //sort K [] non incr
  for ( i = 0 ; i < loop ; i++ )
  {
    for ( j = i+1 ; j < loop ; j++ )
    {
      if ( K[i] < K[j] )
      {
        tmp = K[i] ;
        K[i] = K[j] ;
        K[j] = tmp ;
      }
    }
  }

  //visit K [k_len .. 0] in order to printf K non-desc

  out_len = 0 ;

  for ( i = 0 ; i < loop ; i++ )
  {
    for (j = 0 ; j <  cov_len ; j++)
    {
      if ( K[i] == COVER[j])
      {
        break ;
      }
  
    }

    if ( j==cov_len )
    {
       out[out_len++] = K[i] ;
    }

  }

  for ( i = 0 ; i < out_len; i++ )
  {
    printf("%d" , out[i]) ;
    if ( i != out_len-1 )
    {
      printf(" ") ;
    }
  }

  return 0 ;

}

 

//pass:25  o(≧v≦)o~~

posted on 2013-12-01 10:44  Armin  阅读(658)  评论(0编辑  收藏  举报