九度oj-1033

题目描述:

当n为3时,我们在验证xxx定律的过程中会得到一个序列,3,5,8,4,2,1,将3称为关键数,5,8,4,2称为覆盖数。现在输入n个数字a[i],根据关键数与覆盖数的理论,我们只需要验证其中部分数就可以确定所有数满足xxx定律,输出输入的n个数中的关键数。如果其中有多个关键数的话按照其输入顺序的逆序输出。

输入:

输入数据包含多个用例,每个用例首先包含一个整数n,然后接下来一行有n个整数a[i],其中: 1<=n<=500, 1<a[i]<=1000

输出:

请计算并输出数组a中包含的关键数,并按照其输入顺序的逆序输出,每个用例输出占一行。

样例输入:

3
3 8 4
5
3 8 4 7 15
5
3 8 4 15 7
0

样例输出:

3
15 7 3
7 15 3

代码:

#include<stdio.h>  
#include<string.h>  

int key[1000000];//关键数 key数组要开的尽量大  

int main(){  
int i,n,temp;  
int a[100000];  

//freopen("C:\\Users\\SJF\\Desktop\\acm.txt","r",stdin);   
while(scanf("%d",&n) != EOF && n != 0){  
    //输入数据  
    for(i = 0;i < n;i++){  
        scanf("%d",&a[i]);  
    }  
    memset(key,0,sizeof(key));   
    for(i = 0;i < n;i++){  
        temp = a[i];  
        //求解覆盖数,标记为1  
        while(temp != 1){  
            //如果是偶数,就把temp砍掉一半  
            if(temp % 2 == 0){  
                temp = temp / 2;  
            }  
            //如果是奇数,把temp变成 3*temp+ 1后砍掉一半  
            else{  
                temp = (temp * 3 + 1) / 2;  
            }  
            //出现在求解序列中标记为1  
            key[temp] = 1;  
        }//while  
    }//for  
    int flag = 0;  
    //逆序输出关键数(序列中没有标记为1的即为关键数)  
    for(i = n-1;i >= 0;i--){  
        if(key[a[i]] == 0){  
            if(flag == 1){  
                printf(" ");  
            }  
            printf("%d",a[i]);  
            flag = 1;  
        }  
    }  
    printf("\n");  
}  
return 0;  
}  

或者:

#include<stdio.h>  
#include<string.h>  

int key[1001];  
int a[500];  
int main()  
{  
int n,i,k;  
while(scanf("%d",&n)!=EOF && n != 0)  
{  
    memset(key,0,sizeof(key));  
    for(i = 0;i < n;i++)  
    {  
        scanf("%d",&k);  
        a[i]=k;  
        while(k!=1)  
        {  
            //如果是奇数,把k变成 3*k+ 1后砍掉一半  
            if(k % 2)  
            {  
                k = (k*3+1) / 2;  
            }  
            //如果是偶数,就把k砍掉一半  
            else  
            {  
                k /= 2;  
            }  
            //1<a[i]<=1000  
            //出现在求解序列中标记为1  
            if(k <= 1000)  
            {  
                key[k] = 1;  
            }  
        }  
    }  
    int flag = 0;  
    //逆序输出关键数(序列中没有标记为1的即为关键数)  
    for(i = n-1;i >= 0;i--){  
        if(key[a[i]] == 0){  
            if(flag == 1){  
                printf(" ");  
            }  
            printf("%d",a[i]);  
            flag = 1;  
        }  
    }  
    printf("\n");  
}  
return 0;  
}