PTA-1005 继续(3n+1)猜想

卡拉兹(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

第一次代码(22分,未完全通过测试点)

#include<iostream>
#include<algorithm>
using namespace std;
int count1=0; 
int count3=0;
bool cmp(int a,int b)
{
	return a>b;
}
void guess(int n,int *memory,int *output)//判断3n+1猜想 
{
	int BeginN=n;
	int MiddleN=0;
	int sign=0;//sign=1时表示这个数出现过 
	int count4=0;
	
	for(int i=0;i<count1;i++)
	{
		if(n==memory[i]){
			count4++;
			break;
		}
	}
	if(!count4)
		memory[count1++]=n;
		
	while(n!=1&&!count4){
		if(n%2==0)
			n/=2;
		else
			n=(3*n+1)/2;
			
		int count2=0;
		for(int mn=0;mn<=count1;mn++){
			if(n==memory[mn]&&sign==0){
				sign=1;
				MiddleN=n;
				break; 
			}
			else if(n==memory[mn]&&sign==1)
				break;
			else 
				count2++;
				
			if(count2==count1+1)		//只存储未存过的 
				memory[count1]=n; 
		}
		if(count2==count1+1)
			count1++; 
	}
	int count5=0;
	if(sign){
		for(int i=0;i<count3;i++){
			if(output[i]==MiddleN){
				output[i]=BeginN;
				count5++;
				break;
			}
			else{
				break;
			}
		}
		
		if(!count5){
			output[count3++]=BeginN;
		} 
	}
	else if(!sign&&!count4)
	{
		output[count3++]=BeginN;
	}
}
int main()
{

	int n=0;
	cin>>n;
	int a[n+1]={0},memory[10000]={0},output[10000]={0};
	
	for(int i=0;i<n;i++)
		cin>>a[i];

	for(int i=0;i<n;i++){
		guess(a[i],memory,output);	  	
	}
	sort(output,output+count3,greater<int>());
	for(int nu=0;nu<count3-1;nu++) 
		cout<<output[nu]<<" ";    
	cout<<output[count3-1];
	
	return 0;
} 
 

 对于输入为以下情况时,未通过

输入数据

99
100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2

应当输出数据

100 99 97 96 93 90 88 87 84 82 81 79 78 75 72 69 66 63 60 57 54 51

第一次代码输出数据

100 99 98 97 96 95 93 90 89 88 87 86 85 84 82 81 79 78 77 75 72 69 66 63 60 57 54 51

                                                                                                                                                                                          (2019/2/4)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值