Forever97与未央是一对笔友,他们经常互相写信。有一天Forever97去邮局寄信,发现邮局的收费方式变成了按字收费,收取的费用为总字数除了其自身以外的最大因子。虽然Forever97是一个有情调的人,但他不想因新收费方式而破财,所以他打算把信分成几份寄出去来减少邮费。已知Forever97写的信共有n个字,可以拆成无数封信,也可以不拆,每封信最少为2个字。求Forever97最少需要付多少邮费?
输入描述:
第一行一个正整数T(T<=200),表示共有T组数据。
第2至第T+1行每行一个正整数n(2<=n<=108)。
输出描述:
对每组数据输出一行,即Forever97最少需要付的邮费。
一开始想的是贪心,晒出1e8的素数表,,后来发现时间不允许,再次看题突然想到是否有个定理说的是任意一个合数都能分解为两个素数之和。于是又WA一发。
这个用到了哥德巴赫猜想,以前也做过只不过忘记了。说的是任意一个大于2的偶数都可分解为两个素数之和,任意一个大于7的奇数都能分解为三个素数之和。正确性在于假设一个奇数n,(n-3)显然
是一个偶数,3是一个素数,所以一定能分解为3个质数之和。但是3不一定是最小的解,如果(n-2)是一个质数的话,那么n也能只由两个素数合成。(偶数一定不是质数)
1 #include<bits/stdc++.h> 2 using namespace std; 3 bool isprime(int N) 4 { 5 if(N==2||N==3||N==5) return 1; 6 int m=sqrt(N+0.5); 7 for(int i=2;i<=m;++i) 8 { 9 if(N%i==0) return 0; 10 } 11 return 1; 12 } 13 int main() 14 { 15 int t,n,m,i,j,k; 16 cin>>t; 17 while(t--){ 18 cin>>n; 19 if(isprime(n)) puts("1"); 20 else{ 21 if(n%2==0){ 22 puts("2"); 23 } 24 else{ 25 if(isprime(n-2)) puts("2"); 26 else puts("3"); 27 } 28 } 29 } 30 return 0; 31 }