1005. 继续(3n+1)猜想 (25)

来源:互联网 发布:笔记本无线找不到网络 编辑:程序博客网 时间:2024/06/03 09:38

卡拉兹(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个空格隔开,但一行中最后一个数字后没有空格。

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

7 6

思路分析:

从第一个数开始,进行卡拉兹(Callatz)猜想删除数组中重复出现的数,然后进行排序,不难的

代码如下:

#include<stdio.h>#include<string.h>#define NUM 100void delete_temp(int* candidate, int* n, int* i, int temp);void sort(int* candidate, int n);int main(void) {int n = 0;int candidate[NUM] = { 0 };int i = 0;int temp=0;scanf("%d", &n);while (i < n) {scanf("%d", &(candidate[i]));i++;}for (i = 0; i < n; i++) {temp = candidate[i];while (temp != 1) {if (temp % 2 == 1)temp = (temp * 3 + 1) / 2;elsetemp /= 2;delete_temp(candidate, &n, &i, temp);}}sort(candidate, n);for (i = 0; i < n - 1; i++)printf("%d ", candidate[i]);printf("%d", candidate[i]);return 0;}void delete_temp(int* candidate, int* n, int* i, int temp) {int j,count;for (j = 0; j < *n; j++) {if (candidate[j] == temp) {if(j<*n-1)for (count = j; count < *n - 1; count++)candidate[count] = candidate[count + 1];if (j < *i)(*i)--;(*n)--;break;}}}void sort(int* candidate, int n) {int i, j,temp;for (i = 0; i < n; i++)for (j = i + 1; j < n; j++)if (candidate[i] < candidate[j]) {temp = candidate[i];candidate[i] = candidate[j];candidate[j] = temp;}}



0 0
原创粉丝点击