卡拉兹(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[], cov_len ;
int K[] ,tmp ;
int loop , i,j ;
int out[] , out_len ; scanf ("%d", &loop ) ; cov_len = ; for ( i = ; i < loop ; i++ )
{ scanf("%d" , &X ) ; K[i] = X ; while(X!=)
{
if ( X%)
{
X = (*X+)/ ;
COVER[cov_len++] = X ;
}
else
{
X = X/ ;
COVER[cov_len++] = X ;
}
}
} //sort K [] non incr
for ( i = ; i < loop ; i++ )
{
for ( j = i+ ; 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 = ; for ( i = ; i < loop ; i++ )
{
for (j = ; j < cov_len ; j++)
{
if ( K[i] == COVER[j])
{
break ;
} } if ( j==cov_len )
{
out[out_len++] = K[i] ;
} } for ( i = ; i < out_len; i++ )
{
printf("%d" , out[i]) ;
if ( i != out_len- )
{
printf(" ") ;
}
} return ; }
//pass:25 o(≧v≦)o~~