PAT (Basic Level) Practise (中文)—— 1005. 继续(3n+1)猜想

来源:互联网 发布:java中try catch怎么用 编辑:程序博客网 时间:2024/06/05 04:20

http://pat.zju.edu.cn/contests/pat-b-practise/1005


卡拉兹(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

思路:将递推过程中遇到的数放到一个Binary Search Tree里面,输出时进行查找检查。

PS:数据结构生疏了,BST老是写错,基本功还是不够扎实啊...


#include <stdio.h>#include <stdlib.h>struct Node;typedef struct Node *PNODE;struct Node{int nValue;PNODE pLeft, pRight;Node(int v){nValue = v;pLeft = NULL;pRight = NULL;}};typedef PNODE SearchTree;SearchTree Insert(int v, SearchTree T);SearchTree MakeEmpty(SearchTree T);int Find(int X, SearchTree T);SearchTree Insert(int v, SearchTree T){if (T == NULL){T = new Node(v);return T;}else{if (v < T->nValue)T->pLeft = Insert(v, T->pLeft); // not T = Insert(v, T->pLeft) !!!if (v > T->nValue)T->pRight = Insert(v, T->pRight);}return T;}SearchTree MakeEmpty(SearchTree T){if(T != NULL){MakeEmpty(T->pLeft);MakeEmpty(T->pRight);free(T);}return NULL;}int Find(int X, SearchTree T){if (T != NULL){if (T->nValue == X)return 1;if (X < T->nValue)return Find(X, T->pLeft);else if (X > T->nValue)return Find(X, T->pRight);}return 0;}// 选择排序void sort(int *arr, int len){int i, j;for (i = 0; i < len-1; i++){for (j = i+1; j < len; j++){if (arr[i] < arr[j]){int tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}}}}int inArray[1000];int outArray[1000];int main(){SearchTree T;T = MakeEmpty(NULL);int K;int i, n;scanf("%d", &K);for (i = 0; i < K; i++){scanf("%d", &n);inArray[i] = n;for (;;){if (n == 1)break;if (n%2)// n is oddn = (3*n + 1) >> 1;else// n is evenn >>= 1;T = Insert(n, T);}}int len = 0;for (i = 0; i < K; i++)if (!Find(inArray[i], T))outArray[len++] = inArray[i];sort(outArray, len);// 排序后输出for (i = 0; i < len-1; i++)printf("%d ", outArray[i]);printf("%d\n", outArray[len-1]);T = MakeEmpty(T);return 0;}