poj1142

5 篇文章 0 订阅

题目不难,素数判定+整数唯一分解定理

大致题意为:定义smith数如下:正整数n,满足:令ans=∑ni,ni为n的各个位数字。n=prime1*prime2*prime3……*primen,其中prime i 为素数。令Sum=∑∑primei,其中∑primei表示对于primei素数,其各个位上的数字之和。若Sum=ans且n不为素数,则可以认为n为smith数,现在题目给定一个正整数,要求出比该数大的最小smith数。

题意很明确。主要涉及到素数的判定和整数唯一分解定理。

1)素数判定,这个直接用传统的方法就可以了。时间复杂度为O(log√n)

2)整数唯一分解定理:对于任意的正整数(n>1)都可以唯一的分解成如下的形式:

N=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn)   其中pi均为素数,ki大于0

那么本题要求的实际上就是Sum=∑ki∑primei是否为ans=∑ni。

知道了上面两点,思路应该说很明晰了:枚举比n大的数字,依次判定是否为素数,若不为素数再判定是否满足Sum==ans,若满足则为最小smith数,否则不是,继续枚举。

下面是代码:168K+16MS

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int n,ans;
bool Is_prime(int x){ //判定是否为素数
	for(int i=2;i<=int(sqrt(double(x)));i++)
		if(x%i==0)
			return false;
	return true;
}
bool Is_smith(int x){ //判定是否为smith数
	int Sum=0;
	int i=2;
	while(i*i<=x){ //筛法求整数分解素数各项(值和幂)
		if(x%i==0){ //若可以整除
			int s=0,temp=i;
			while(temp>0){ //求该素数个位累计之和
				s+=temp%10;
				temp/=10;
			}
			int j=0; //求该素数因子的幂
			while(x%i==0){
				j++;
				x/=i;
			}
			Sum+=s*j; //累加 j 个 s
		}
		if(i==2) //若为2,则下一个奇数为3
			i++;
	    else //否则为奇数,下一个奇数为i+2
			i+=2;
	}
	if(x!=1){ //若还没有整除完毕,则x为素数因子,其幂为1
		while(x>0){ // 累加x的各位之和
			Sum+=x%10;
			x/=10;
		}
	}
	if(Sum==ans) //判断是否相等
		return true;
	return false; //不相等
}
int main(){
  while(scanf("%d",&n),n){
		n++; //从n+1开始枚举
	while(true){
			if(!Is_prime(n)){ //先判断是否为素数
				ans=0;
		        int temp=n;
		        while(temp>0){ //累加求n的各位之和
					ans+=temp%10;
					temp/=10;
				}
				if(Is_smith(n)){ // 若为smith数,则输出最小数,退出
					printf("%d\n",n);
					break;
				}
			}
			n++; //否则继续枚举
	}
  }
	return 0;
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值