卡拉茲(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輸出格式:每個測試用例的輸出佔一行,按從大到小的順序輸出關鍵數字。數字間用1個空格隔開,但一行中最後乙個數字後沒有空格。
輸入樣例:
6輸出樣例:3 5 6 7 8 11
7 6時間限制
400 ms
記憶體限制
65536 kb
**長度限制
8000 b
判題程式
standard 作者
chen, yue
演算法思路:
簡單模擬。 設定乙個 flag 陣列記錄計算過程中的數字,初始全部置為 false。 則: 對原數列每乙個數字進行計算,若這個數字為 true 則直接跳過,否則,對其進行題目要求的計算同時並設為 true(這裡注意一點,計算3,過程是3、5、8、4、2、1, 不把3本身設為 true 的,題目就是計算當前數字時把除自己外的計算序列中設為 true,否則全體都是 true 了); 再排序並從大到小記錄原序列對應為 false 的數字再輸出即可(我的**中用 ansnum 是為了最後輸出格式考慮的)
**:
#include #include #include #include #include #include using namespace std;
int main();
for (int i = 0; i < n; ++i)
bool flagnumber[10000];
memset(flagnumber,false,sizeof(flagnumber));
int temp;
for (int i = 0; i < n; ++i)
else
temp = temp/2;
flagnumber[temp] = true;}}
}sort(num,num+n);
int ansnum=0; // 數有幾個
for (int i = n-1; i >= 0; --i)
//// for (int i =0; i < 15; ++i)
// cout << flagnumber[i] << " ";
// cout << endl;
for (int i = n-1; i >= 0; --i)
else
cout << num[i];
ansnum--;}}
return 0;
}
反思:1, 這份**是 ac **。但我第一次提交中是這樣的:
3答案錯誤
5384
0/34
段錯誤5
3840/3
可以看到,測試點3錯誤,測試4段錯誤。 段錯誤原因之一是陣列越界。然後我才反應過來是 flagnumber 開小了,於是從120改為了10000就過了。當然也可以在計算過程中加乙個判斷。
2, 如果為了時間考慮。則上面加上判斷,避免冗餘操作。再在計算中,多新增判斷條件,如果是計算中,得到了之前算過的數字則跳出
1005,繼續(3n 1)猜想,PAT
時間限制 400 ms 記憶體限制 65536 kb 長度限制 8000 b 判題程式 standard 作者 chen,yue 卡拉茲 callatz 猜想已經在1001中給出了描述。在這個題目裡,情況稍微有些複雜。當我們驗證卡拉茲猜想的時候,為了避免重複計算,可以記錄下遞推過程中遇到的每乙個數。...
PAT1005 繼續 3n 1 猜想
卡拉茲 callatz 猜想已經在1001中給出了描述。在這個題目裡,情況稍微有些複雜。當我們驗證卡拉茲猜想的時候,為了避免重複計算,可以記錄下遞推過程中遇到的每乙個數。例如對n 3進行驗證的時候,我們需要計算3 5 8 4 2 1,則當我們對n 5 8 4 2進行驗證的時候,就可以直接判定卡拉茲猜...
PAT(乙級)1005 繼續 3n 1 猜想
題目 卡拉茲 callatz 猜想已經在1001中給出了描述。在這個題目裡,情況稍微有些複雜。當我們驗證卡拉茲猜想的時候,為了避免重複計算,可以記錄下遞推過程中遇到的每乙個數。例如對n 3進行驗證的時候,我們需要計算3 5 8 4 2 1,則當我們對n 5 8 4 2進行驗證的時候,就可以直接判定卡...