1005続行(3n + 1)予想(25ポイント)
カラッツ予想は1001年に記述されています。このテーマでは、状況はもう少し複雑です。
Karaz予想を検証するとき、繰り返し計算を避けるために、再帰プロセスで遭遇したすべての数を記録できます。
たとえば 、 n = 3を検証する場合、3、5、8、4、2、1を計算する必要があります 。n = 5、8、4、4、2を検証する場合、Karaz予想を直接決定できます。これらの4つの数値は、3を検証するときにすでに検出されているため、計算を繰り返す必要はありません。5、8、4、2は、3で「カバーされる」と呼ばれます。シーケンス内の他の番号でnをカバーできない場合、シーケンス内の特定の番号nを「キー番号」 と呼び ます。
検証する一連の番号が与えられたので、検証する必要があるのはいくつかの主要な番号のみであり、残りの番号を再度検証する必要はありません。あなたの仕事は、これらのキー数値を見つけ、最大から最小の順に出力することです。
入力フォーマット:
各テスト入力には1つのテストケースが含まれます。最初の行は正の整数 K(<)を示し、2番目の行は 検証するKの異なる正の整数n(1)を示します 。別に。
出力フォーマット:
各テストケースの出力は1行を占め、キー番号は最大から最小の順に出力されます。番号はスペースで区切られますが、行の最後の番号の後にスペースはありません。
入力例:
6
3 5 6 7 8 11
出力例:
7 6
1 #include <iostream>
2
3 #include <algorithm>
4 #include <vector>
5 #include < string >
6
7
8
9 名前空間std を使用 ;
10 11 bool is_contain_this_num(vector < int > nums 、int a)
12 {
13 for(int i = 0 ; i <nums.size(); ++ i)
14 {
15 if(a == nums [i])
16 {
17 返品
真;
18 }
19 }
20は falseを返し ます。
21 }
22
23
24 bool cmp(int s1、int s2)
25 {
26 return s1> s2;
27 }
28
29 int main()
30 {
31 int numcount;
32 cin >> numcount;
33 vector < int > nums;
34 のための(int型i = 0 ; i <numcount; ++ i)
35 {
36 int num;
37 cin >> num;
38 nums.push_back(num);
39 }
40
41 // メモリーを通過する数
42 vector < int > check_vec;
43 for(int i = 0 ; i <nums.size(); ++ i)
44 {
45 int n = nums [i];
46 if(!is_contain_this_num(check_vec、n))
47 {
48 while(n!= 1 ){
49 if(n%2 == 0 )
50 {
51 n / = 2 ;
52 } else
53 {
54 n =(3 * n + 1)/ 2 ;
55 }
56 if(!is_contain_this_num(check_vec、n))
57 {
58 check_vec.push_back(n);
59 }
60 }
61 }
62 }
63
64 vector < int > result;
65 for(int i = 0 ; i <nums.size(); ++ i)
66 {
67 bool flag = false ;
68 for(int j = 0 ; j <check_vec.size(); ++ j)
69 {
70 if(nums [ i] == check_vec [j])
71 {
72 フラグ= true ;
73 }
74 }
75 if(!フラグ)
76 {
77 result.push_back(nums [i]);
78 }
79 }
80 sort(result.begin()、result.end()、cmp);
81
82 のために(ベクトル< INT!;それ= result.end();> ::イテレータがresult.beginを()=それ++ )
83 {
84 COUT << * こと。
85 if(it!= result.end()- 1 )
86 {
87 cout << " " ;
88 }
89 }
90 return 0 ;
91 }