1005 继续(3n+1)猜想 (25 分)

在这里插入图片描述

思路
1、定义一个vector v来保存输入的值。
2、定义一个大数组arr[10000]来标记出现过的值(hash散列),作用在于:n值在每运算一次(如n /= 2)之后,都将a[n] = 1;表示该数n已经出过一次了。
3、遍历vector中的值,若arr[v[i]] == 0;表示该数还没出现过,为关键值。

注意
1、大数组一般定义成全局的(main函数外边),防止栈溢出。调用的cmp子函数也定义到外边。
2、关于vectord的使用
	定义和初始化:
	vector<int> a; //相当于定义了一个长度可变的int类型的一维数组int a[];
	a.resize(8); //将变量a的长度resize为8,默认这8个元素都是0.
	vector<int> a1(10); //直接定义长度为10的int数组,默认这10个元素值都为0.
	vector<int> a2(100, 9);// 把100长度的数组中所有的值都初始化为9.
	vector<int> a3[10];//此处是中括号,此处相当是一个于二维int数组,
					   //即a3[0]~a3[9]中每一个都是vector容器.
	排序:
	vector<int> v;
	sort(v.begin(),v.end(),cmp);//sort函数默认从小到大排,可通过添加参数cmp修改规则
	
3.此处这种以空间换时间的解法需要记住
4.此处通过添加flag和if()来实现题目要求的空格格式输出.先输出空格,后输出值.

代码 v.1

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

//1.main函数的外边定义一个大数组来标记出现过的值(hash散列),cmp用来给定sort排序规则
int arr[10000];
bool cmp(int a,int b){
    return a > b; //从大到小排序规则
} 
int main(){
    int k,flag = 0; //flag用于后边控制输出格式
    cin >> k;
    //2.定义vector来存储输入的值,对每个值循环计算,并标记出出现过的值
    vector<int> v(k); 
    for(int i = 0;i < k;i++){
       cin >> v[i];
       int n = v[i];
        
       while(n != 1){
           if(n % 2 != 0)
               n = (3 * n + 1);
           n = n/2;
           arr[n] = 1;  //在大数组中标记
       }
    }
    //3.对vector排序,按照格式输出
    sort(v.begin(),v.end(),cmp);
    for(int i = 0;i < k;i++){
        if(arr[v[i]] == 0){
            if(flag == 1)cout << " "; //先输出空格,再输出数字,避免了最后的数字后边的空格。
            cout << v[i];
            flag = 1;
        }
    }
    return 0;
}

代码v.2
优化
1、while里边添加break;减少计算量
2、变量n改在循环外边定义(函数开头),减小空间复杂度

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

//1.main函数的外边定义一个大数组来标记出现过的值(hash散列),cmp用来给定sort排序规则
int arr[10000];
bool cmp(int a,int b){
    return a > b; //从大到小排序规则
} 
int main(){
    int k,n,flag = 0; //flag用于后边控制输出格式
    cin >> k;
    //2.定义vector来存储输入的值,对每个值循环计算,并标记出出现过的值
    vector<int> v(k); 
    for(int i = 0;i < k;i++){
       cin >> v[i];
       n = v[i];
        
       while(n != 1){
           if(n % 2 != 0)
               n = (3 * n + 1);
           n = n/2;
           if(arr[n] == 1) //出现重复的就不用继续计算了
               break;
           arr[n] = 1;  //在大数组中标记
       }
    }
    //3.对vector排序,按照格式输出
    sort(v.begin(),v.end(),cmp);
    for(int i = 0;i < k;i++){
        if(arr[v[i]] == 0){
            if(flag == 1)cout << " "; //先输出空格,再输出数字,避免了最后的数字后边的空格。
            cout << v[i];
            flag = 1;
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值