• PAT 乙级 1005 继续(3n+1)猜想 (25) C++版


    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

    思路:建造两个set容器,s1存储所有数变为1过程中产生的数,s2则存储关键数
    注意点:后续输入的数覆盖了前面的数,所以需要判断变为1的过程中是否包含了关键数中的关键数,如果有,将这个关键数删除

     1 // 1005.cpp : 定义控制台应用程序的入口点。
     2 //
     3 
     4 #include "stdafx.h"
     5 #include<iostream>
     6 #include<algorithm>
     7 #include<set>
     8 
     9 using namespace std;
    10 
    11 void get_num(int n, set<int>& s1, set<int>& s2);
    12 
    13 int main()
    14 {
    15     int N,temp;
    16 
    17     //s1为所有输入的数变成1过程中产生的数
    18     //s2为关键数
    19     set<int> s1,s2;
    20 
    21     cin >> N;
    22 
    23     for (int i = 0; i < N; ++i)
    24     {
    25         cin >> temp;
    26 
    27         //如果输入的数没有被其他的数覆盖
    28         if (find(s1.begin(), s1.end(), temp) == s1.end())
    29         {
    30             s2.insert(temp);
    31             get_num(temp, s1, s2);
    32         }
    33     }
    34 
    35     set<int>::reverse_iterator i,end = s2.rend();
    36 
    37     for (i = s2.rbegin(); i != end; ++i)
    38     {
    39         if (i == s2.rbegin())
    40             cout << *i;
    41         else
    42             cout << " " << *i;
    43     }
    44 
    45     cout << endl;
    46 
    47     return 0;
    48 }
    49 
    50 void get_num(int n,set<int>& s1,set<int>& s2)
    51 {
    52     int i;
    53 
    54     s1.insert(n);//将该数也插入容器中,防止后面的数覆盖此数而未检查到
    55 
    56     while (n != 1)
    57     {
    58         if (n & 1)
    59             n = 3 * n + 1;
    60 
    61         n /= 2;//无论奇偶都会除以2
    62 
    63         if (find(s2.begin(), s2.end(), n)!=s2.end())
    64         {
    65             s2.erase(n);//如果该数覆盖前面的数,则将前面的数从关键数容器删除
    66 
    67             break;
    68         }
    69 
    70         s1.insert(n);
    71     }
    72 }
  • 相关阅读:
    adb shell am force-stop <package>
    推荐一个代码生成工具:freemarker
    子控件跟着父控件变色
    sqlite支持的数据库类型
    android 资源文件
    一个手机基础信息的获取代码
    二维码的开源项目
    在点击HOME键时, 在点击icon回到原来的应用。
    Wireshark "The NPF driver isn’t running…"
    .atomic vs volatile
  • 原文地址:https://www.cnblogs.com/cdp1591652208/p/7236499.html
Copyright © 2020-2023  润新知