PAT_B_1005 继续(3n+1)猜测

题目描述:数组

卡拉兹(Callatz)猜测已经在1001中给出了描述。在这个题目里,状况稍微有些复杂。
当咱们验证卡拉兹猜测的时候,为了不重复计算,能够记录下递推过程当中遇到的每个数。例如对 n=3 进行验证的时候,咱们须要计算 三、五、八、四、二、1,
则当咱们对 n=五、八、四、2 进行验证的时候,就能够直接断定卡拉兹猜测的真伪,而不须要重复计算,由于这 4 个数已经在验证3的时候遇到过了,
咱们称 五、八、四、2 是被 3“覆盖”的数。咱们称一个数列中的某个数 n 为“关键数”,若是 n 不能被数列中的其余数字所覆盖。 如今给定一系列待验证的数字,咱们只须要验证其中的几个关键数,就能够没必要再重复验证余下的数字。你的任务就是找出这些关键数字,并按从大到小的顺序输出它们。 输入格式: 每一个测试输入包含 1 个测试用例,第 1 行给出一个正整数 K (<100),第 2 行给出 K 个互不相同的待验证的正整数 n (1<n≤100)的值,数字间用空格隔开。 输出格式: 每一个测试用例的输出占一行,按从大到小的顺序输出关键数字。数字间用 1 个空格隔开,但一行中最后一个数字后没有空格。
输入样例: 6 3 5 6 7 8 11 输出样例: 7 6

主要思想:测试

利用一个数组,初始置零,用于标记某个数字是否为关键数;

并在运算过程当中添加一个计数器,记录关键数的个数;

最后,倒序遍历数组,若是标记为1则打印输出关键字。

本人代码:spa

//  Guess Number from 3*n+1 -> 1
//  Go ahead
//  这种解法(22/25) 最后一个测试点过不去 
//  上述问题已经解决,在代码 47行,48行给出了部分解释 
/*
当咱们验证卡拉兹猜测的时候,为了不重复计算,
能够记录下递推过程当中遇到的每个数。例如对 n=3 进行验证的时候,
咱们须要计算 三、五、八、四、二、1,则当咱们对 n=五、八、四、2 进行验证的时候,
就能够直接断定卡拉兹猜测的真伪,而不须要重复计算,
由于这 4 个数已经在验证3的时候遇到过了,
咱们称 五、八、四、2 是被 3“覆盖”的数。咱们称一个数列中的某个数 n 为“关键数”,
若是 n 不能被数列中的其余数字所覆盖。
如今给定一系列待验证的数字,咱们只须要验证其中的几个关键数,
就能够没必要再重复验证余下的数字。
你的任务就是找出这些关键数字,并按从大到小的顺序输出它们。
*/

# include <stdio.h>

int main(void)
{
	int k;  // 输入一个整数 k<100
	int n, temp;
	int i;
	int table[101] = {0};  //  记录数据是否出现  (不用再单独排序)
	// 定义为300 不会出现数组越界的状况 
	int val = 0; // 记录 最终table 中有多少个不为零的数 
	
	scanf("%d",&k);
	for (i=0; i<k; i++)
	{
		scanf("%d",&temp);
		table[temp] = 1;
	}
	
	for (i=1; i<=100; i++)
	{
		//  若是此数字在table中出现过,则进行运算 
		if (1 == table[i]) 
		{
			n = i;
			while(n>1)
			{
				if (n%2 == 0)
					n = n/2;
				else
					n = ((3*n)+1)/2; 
// 若是此处写 n = 3*n+1 则会在最后一个测试点没法经过,没有仔细的看数字猜测过程,(3*n+1)/2 
				//  判断计算过程当中的数是否在输入数组中出现	
				
				//  注:在提交过程当中 若是直接判断 table[n] (n==100)可能会出现数组越界的状况 
				if (n<=100 && n>=2)
				{
					table[n] = 0;
				}
					
			}
				
		}
	}

	//  输出table中不为0 的下标的个数 
	for (i=100; i>=1; i--) 
	{
		if (1 == table[i]) 	
			val++; 
	}
	
	for (i=100; i>=1;  i--)
	{
		if (1==table[i])
		{
			printf("%d",i);
			val--;
			if (val != 0)
				printf(" ");
		}
		
	}
	return 0;
}
相关文章
相关标签/搜索