刷題訓練——PAT(Basic Level)-1005

快開學了纔開始學習之旅。

最近幾天在看數論基礎,然而看完1/4後卻發現後面的一竅不通。

萬分掙扎後,決定把它先放放,刷刷題。

學習還是不能浮躁,時刻讓自己平靜下來。


1005. 繼續(3n+1)猜想 (25)

時間限制
400 ms
內存限制
65536 kB
代碼長度限制
8000 B
判題程序
Standard
作者
CHEN, Yue

卡拉茲(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個空格隔開,但一行中最後一個數字後沒有空格。

輸入樣例:
6
3 5 6 7 8 11
輸出樣例:
7 6

FROM:https://www.patest.cn/contests/pat-b-practise/1005


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int table[105][105];
int data[105];
void running(int i,int mom,int &k)
{
    if(i!=mom)
        table[mom][++k]=i;
    if(i==1)return;
    else if(i%2){
        running((3*i+1)/2,mom,k);
        return;
    }
    else
        running(i/2,mom,k);
    return;
}
bool exsearch(int father,int son)
{
    if(!father||!son||father==son)return 0;
    for(int i=1;i<table[father][0];++i){
        if(son==table[father][i])
            return 1;
    }
    return 0;
}
int main()
{
    memset(table,0,sizeof(table));
    memset(data,0,sizeof(data));
    for(int i=2;i<101;++i)//draw up a table
        running(i,i,table[i][0]);
    int K;
    scanf("%d",&K);
    for(int i=0;i<K;++i)
        scanf("%d",&data[i]);//loading
    for(int i=0;i<K;++i){
        for(int j=0;j<K;++j){
            if(exsearch(data[i],data[j]))
                data[j]=0;
        }
    }
    sort(data,data+K);
    printf("%d",data[K-1]);
    for(int i=K-2;i>0&&data[i]!=0;--i){
        printf(" %d",data[i]);
    }
    printf("\n");
    return 0;
}


本來自己在紙上分析,構造出一顆樹,然而不會數據結構。

突發奇想打表比較,反正數也不大,超時?誰知道呢~!

試試就過了。dalao們的優化方法以後再看吧。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章