hdu1999 不可摸数



设输入n,因为1是所有数的约数,首先t=n-1;

如果此时 t 为素数,则n一定能被找到,eg:t*t,由于t是素数,t*t 的约数有且只有1和t,所以成立。
否则,如果 t 能表示为两个互不相等的素数的和,则n一定找到。
eg:i 为素数且t-i 也为素数,则 i*(t-i) 的约数一定只有 1,i ,t-i; 所以成立。
但是,if(i==(t-i)),则不一定,因为相同素数只取一次。

证毕。

//转发

#include<iostream>
using namespace std;

int main(){

	int n, t, i, j, q;
    int a[1001]={0};
	a[0]=1; a[1]=1;

    for(i=2; i<=1000; i++){

		if(a[i]==0){            
			for(j=i+i; j<=1000; j=j+i){  //若j为i的倍数则标记为1;
			    a[j]=1;
			}
		}
	}      //至此,标记为0的全为素数;

    cin>>t;
	while(t--){
	    cin>>n;
		n=n-1;    
        q=0;
		if(a[n]==0)  //此时 n 为素数,则n一定能被找到;
			q=1;
		else{
			for(i=2; i<=n/2; i++){
				if(a[i]==0 && a[n-i]==0 && i!=n-i){  //i 为素数且n-i 也为素数,则 i*(t-i) 的约数一定只有 1,i ,t-i;
				    q=1;break;
				}
			}
		} 
         if(q==0) cout<<"yes"<<endl;
		 else cout<<"no"<<endl;
	}

    return 0;
}


#include <stdio.h>

int arr[1005];

void init()
{
	int sum,i,j;
	for (i=2;i<=2000;i+=2)
	{
		sum=0;
		for (j=1;j<=i/2;j++)
		{
			if(i%j==0)
				sum+=j;
		}
		if(sum<=1000)
			arr[sum]=1;
	}
	for(i=3;i<=1000;i+=2)
	{
		sum=0;
		for(j=1;j<=(i*i)/2;j+=2)
			if((i*i)%j==0)
				sum+=j;
		if(sum<=1000)
			arr[sum]=1;
	}
}

int main()
{
	int t,n;
	init();
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d",&n);
		if(n==5||n==2)
			printf("yes\n");
		else
		{
			if(arr[n]||n%2==1)
				printf("no\n");
			else
				printf("yes\n");
		}
	}
	return 0;
}

/*对于这个题有两个引理和公认:
1.     若x为大于2的偶数,那么s(x)>x/2;
2.     若x是一个正奇数,而s(x)是偶数,那么x必然是一个平方数。
3.     只有一个不可摸数是奇数,那是5
有以上三个结论,便可以算出一定范围内的不可摸数。*/




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值