卡拉茲(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
建立四個陣列。將所有計算的覆蓋數存起來,再和輸入資料對照。如果輸入資料有,則說明輸入的資料不是關鍵數,篩選之後,最後剩下的輸入資料就是關鍵數了。這種方法容易理解,但是技巧性顯然不足,因為需要將後面的所有數字的關鍵數都計算出來。實際上,後面的數字經過判斷,有些數字是不需要計算的。n=6
}使用vector容器儲存,使用的sort()函式進行排序。一次將所有資料存入vector,計算每個數字的覆蓋數之後,就將後面vector中屬於覆蓋數的數字進行標記,賦值為0。這樣後面只要進行非零數就可以跳過是覆蓋數的vector。最後進行sort()排序
vector知識點:
c++ vector 容器**基本用法:sort()函式:#include < vector>
using namespace std;
//向量(vector)是乙個封裝了動態大小陣列的順序容器
//能夠存放任意型別
簡單介紹:vector《型別》識別符號(最大容量);
sort()函式c++#include< algorithm> //所屬標頭檔案?sort(begin,end,cmp); //其中cmp引數可以省略,省略後預設公升序排序
?如果要進行降序排序,需要另外定義cmp函式:
;//將非keynum置零
for(
int j=
0;j}}
}sort
(m.begin()
,m.end()
,cmp)
;//根據cmp的返回值型別確定排序方式 // 2
for(
int i=
0;i) flag=1;
}return0;
}vector也可以不申請大小,動態申請,採用v.push_back(i)。但是一定不能先申請大小,又v.push_back(),因為這樣會把申請大小的vector都認為是0,也帶進去
#include
#include
#include
using
namespace std;
bool
cmp(
int a,
int b)
intmain()
; vector<
int> v;
for(
int i=
0;isort
(v.begin()
,v.end()
,cmp)
;for
(int i=
0;isize()
;i++)}
return0;
}
上面的公升級版可以很好地解決這個問題。但是隨之而來的問題是必須要使用者全部輸入才可以進行判斷。也就是現在根據使用者輸入的某乙個數字,只能針對之前輸入的資料有效。此次輸入的數字是不是關鍵數已經形成結論,無法在後續輸入計算後調整之前的是不是關鍵數的判斷。帶來的問題也顯然,就是時間複雜度2*o(n)。因為前後有兩個0~n-1的for迴圈。
雜湊雜湊就可以解決這個問題,並且將時間複雜度降低到公升級版的一般,也就是o(n)。這也是理論上最低的時間複雜度了。
雜湊雜湊的思想是這樣的:類似於函式因變數與自變數的關係,自變數到因變數的對映只能是一對一和多對一。因此,在計算出使用者輸出的某個數字的覆蓋數之後,將覆蓋數部分放置在乙個新陣列中,並全部置1,這樣當有新的數字計算後使得原來不是覆蓋數的原始數字也會置1。這樣,最後剩下的就是沒有置1的數字,它們就是關鍵數。
這裡存在兩個對映:每乙個inputnum,會將其覆蓋數全部置1;
每乙個輸入數字的序號對應乙個inputnum.
因此只要每乙個輸入數字序號對應的數字的雜湊陣列值仍然為0,就說明不是覆蓋數,就可以輸出。對應**3部分。
對每乙個輸入的數字n進行驗證,把驗證過的數字對應的arr標記為1,然後對這些輸入的數字從大到小排序,輸出所有arr=0的數字即為關鍵數字~
#include
#include
#include
using
namespace std;
int arr[
10000];
//定義了乙個全域性陣列 +
bool
cmp(
int a,
int b)
//int
main()
tmp/=2
;if(arr[tmp]==1
)break
; arr[tmp]=1
;}}sort
(m.begin()
,m.end()
,cmp)
;//根據cmp的返回值型別確定排序方式
for(
int i=
0;isize()
;i++)}
return0;
}
1005繼續3n 1猜想
卡拉茲 callatz 猜想已經在1001中給出了描述。在這個題目裡,情況稍微有些複雜。當我們驗證卡拉茲猜想的時候,為了避免重複計算,可以記錄下遞推過程中遇到的每乙個數。例如對n 3進行驗證的時候,我們需要計算3 5 8 4 2 1,則當我們對n 5 8 4 2進行驗證的時候,就可以直接判定卡拉茲猜...
1005 繼續 3n 1 猜想
卡拉茲 callatz 猜想已經在1001中給出了描述。在這個題目裡,情況稍微有些複雜。當我們驗證卡拉茲猜想的時候,為了避免重複計算,可以記錄下遞推過程中遇到的每乙個數。例如對n 3進行驗證的時候,我們需要計算3 5 8 4 2 1,則當我們對n 5 8 4 2進行驗證的時候,就可以直接判定卡拉茲猜...
1005 繼續 3n 1 猜想
時間限制 400 ms 記憶體限制 65536 kb 長度限制 8000 b 判題程式 standard 作者 chen,yue 卡拉茲 callatz 猜想已經在1001中給出了描述。在這個題目裡,情況稍微有些複雜。當我們驗證卡拉茲猜想的時候,為了避免重複計算,可以記錄下遞推過程中遇到的每乙個數。...