[PAT Basic Level] 1005. continue (3n + 1) guess

Topic analysis

This question is more complex at first glance, it is not easy to think of any better coping strategies, at least I did not expect. So there is no way, the simple idea of ​​brute force hard dry.

The goal is to identify those "key number", a little analysis can know, this actually refers to delete those Kharazi will appear in the other sequence number (here called the rule a number of operations carried out by Kharazi guess, until a number sequence generated) of.

So you can come up with such an approach:
starting from the first number, find its Kharazi sequence, then the whole array of all elements other than the current number of traverse, find all the numbers appear in the Kharazi sequence , delete (also "reduce" the size of the search back). After then move to the next number, repeat the previous work, until the complete cycle through the array.

You can see so frequently "delete" elements in the array, then I would use the words of the array will be needed frequently shift, obviously this is very complex, with the list seems to have some waste. So an alternative is to create an additional bool array corresponds to characterize elements in the array is also effective, if they are deleted bool value corresponding number will be modified to false.

When calculating Kharazi sequence, since the length of the unknown, the array do not want to waste too much open space, the dynamic expansion means may be employed.

Finally traversed the "Delete" out of all non-critical elements, the title also requires us to output in descending order, so also need to iterate over the array, to identify those key elements surviving, the other with an array of conservation, in order here convenient, because the topic has told us not more than 100 elements, so a direct open int array of size 100 to save, you can output after reordering again.

Optimization strategies
more note about the condition of the subject, the subject can be found tell us the element size does not exceed 100, Kharazi sequence before each time we do not save the calculation of more than 100 elements, which would reduce the size of the array, reduce traverse and comparison of time.

The whole idea of ​​this topic by dry down, still somewhat cumbersome, and finally sorted in order to write less code simply by insertion sort. But compared to the previous comparative complexity and delete elements, ordering that several elements of the remaining time is almost negligible, so do not write very good performance sorting algorithms, a simple right on the line.

Source

#include <stdio.h>

const int DEFAULT_SIZE=30;   //设置储存卡拉兹序列数组默认大小为30,满后再进行扩容
void expand(int *&arr,int len);  //对数组扩容
int* findPath(int num,int &len);  //计算卡拉兹猜想过程数
void insertSort(int *arr,int len);   //插入排序

int main()
{
    int caseNumber;
    scanf("%d",&caseNumber);
    getchar();
    int *value=new int[caseNumber];  //储存元素值
    bool *isValid=new bool[caseNumber];  //判断元素是否还有效
    for(int i=0;i<caseNumber;++i){  //读取数据
        scanf("%d",&value[i]);
        isValid[i]=true;  //初始化为true
    }
  
    for(int i=0;i<caseNumber;++i){
        if(!isValid[i]) continue;
        int len=0;
        int* path=findPath(value[i],len);  //计算当前有效元素的卡拉兹路径元素
        for(int j=0;j<caseNumber;++j){  //对除当前元素外所有元素进行遍历,删除被覆盖元素
            if(!isValid[j]||j==i) continue;
            for(int k=0;k<len;++k){
                if(path[k]==value[j]){  //发现路径上的元素,删除
                    isValid[j]=false; 
                    break;
                }
            }
        }
       delete []path;  //释放当前路径数组的空间
    }
    int keys[100];  //剩余数个数不超过100
    int count=0;
    for(int i=0;i<caseNumber;++i){
        if(!isValid[i]) continue;
        keys[count++]=value[i];  //记录剩下的关键数
    }
    insertSort(keys,count);
    for(int i=0;i<count-1;++i)
        printf("%d ",keys[i]);
    printf("%d",keys[count-1]);
    delete []value;
    delete []isValid;
    return 0;
}

void expand(int *&arr,int len)
{
    int *old=arr;
    arr=new int[len*2];  //扩容为原来两倍
    for(int i=0;i<len;++i)
        arr[i]=old[i];
    delete []old;   //释放原空间
}
int* findPath(int num,int &len)
{
    len=1;
    int curSize=1;
    int capacity=DEFAULT_SIZE;
    int * path=new int [capacity];
    path[0]=num;  
    while(num!=1){
        len++;
        if(num%2==0)  num>>=1;
        else num=(3*num+1)>>1;
        if(num<101) path[curSize++]=num;  //仅当所得数值小于101时放入数组
        if(curSize==capacity){  //若数组满,扩容
            capacity<<=1;
            expand(path,curSize);
        }
    }
    return path;
}
void insertSort(int *arr,int len)
{
    for(int i=1;i<len;++i){
        int curOrder=i;
        int pre=i-1;
        while(arr[curOrder]>arr[pre]){
            int tmp=arr[curOrder];
            arr[curOrder--]=arr[pre];
            arr[pre--]=tmp;
            if(curOrder==0) break;
        }
    }
}
发布了11 篇原创文章 · 获赞 1 · 访问量 74

Guess you like

Origin blog.csdn.net/weixin_44452361/article/details/104602637