C++版浙大PAT乙级1005(25分)

https://pintia.cn/problem-sets/994805260223102976/problems/994805320306507776

2021.3.8改进版本

一开始一边输入一边找关键数,但是发现不行,必须是全部输入完成后再找出关键数。

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

int cover[100000]={0};

bool cmp(int a, int b){
	return a > b;
}

int main(){
	int n, t;
	cin >> n;
	int num[n], res[n], k=0;
	for(int i=0; i<n; i++){
		cin >> num[i];
		t = num[i];
        // 标记覆盖数
		while(t != 1){
			if(t%2 != 0){
				t = 3*t+1;
            }
			t /= 2;
            // 已经标记过,后面就跳过了
			if(cover[t]==1){
				break;
			}
			cover[t] = 1;
		}
	}
    // 从输入的数中找出没被覆盖的数,即关键数
	for(int i=0; i<n; i++){
		if(cover[num[i]]==0){
			res[k++] = num[i];
		}
	}
    // 从大到小排序
	sort(res, res+k, cmp);
    // 输出
	for(int i=0; i<k; i++){
		cout << res[i];
		if(i<k-1)
			cout << " ";
	}
	return 0;
}

 

2021.1.31日版本

回顾一下1001的题:

对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3n+1) 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 n=1。对给定的任一不超过 1000 的正整数 n,简单地数一下,需要多少步(砍几下)才能得到 n=1。

这个题不一样的是,输入n个数,如:3、5、6、7、8、11,遍历每个数,

对于m=3,每一步得到的数分别为10、5、8、4、2,这些数被称为覆盖数;

对于m=7,覆盖数为11、17、26、13、20、10(5、8、4、2),括号内不用算了;

对于m=5、m=8和m=11,因为它已经是覆盖数所以不用再计算了;

所以m=6和m=7没被任何数覆盖,它们被称为关键数。

这道题就是要求一串数字中的关键数。

#include<iostream>
using namespace std;

int num[10000], cover[10000];

void addCover(int n){
	while(n!=1){
		// 数处理
		if(n % 2 == 0)
			n /= 2;
		else
			n = ((n*3)+1)/2;

		// 如果覆盖数里面没有这个数,把这个数加入到覆盖数
		if(cover[n] == 0 && n <= 100){
			cover[n] = n;
			if(num[n] == n)
				num[n] = 0;
		}else if(cover[n] != 0){
			break;
		}

	}
}

int main(){
	int n, m, max = -1, flag = 0;
	cin >> n;

	for(int i=0; i<n; i++){
		cin >> m;
		if(m > max)
			max = m;
		num[m] = m;
		// 如果覆盖数里面没有这个数,添加它的覆盖数进行处理
		if(cover[m]==0){
			addCover(m);
		}else{
			num[m] = 0;
		}
	}
	// 输出
	for(int i=max; i>=0; i--){
		if(num[i] == 0) continue;
		if(flag > n)	break;
		if(flag > 0)
			cout << " ";
		cout << num[i];
		flag ++;
	}
	
	return 0;
}

最开始的时候会报两个段错误,因为数组越界,所以把两个数组的个数扩大100倍。

后面又报了一个答案错误,因为 n = ((n*3)+1)/2 时,忘记除以2了,但是为什么还是有四个点通过了呢,因为它还是会在下一次循环的时候除以2。

最后终于通过了,哈哈!谢谢男朋友帮忙~

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值