Description

阿强愉快的拿到了自己工资,可是抠门的他发现自己还要没有交税。X国采用一种奇怪的税收方式。对于工资

num,需要收的税是p,p为num的最大的除数并且p不等于num。

(ps:6的最大除数是3,25的最大除数是5,2的最大除数是1)

为了减少人们要交的税,X国又规定可以把钱分开算税,分开的个数不限,即n1 + n2 + ... + nk = n,要交的

税就是每个部分的总和。

阿强现在向你寻求帮助,给定X最少要交多少钱的税?

Input

数据的组数 T;(T<=2000)

接下来T行,每行一个数字X(2 <= X <= 2e9)

Output

 对于每行X,输出最少的税Y

 

Sample Input

3
11
27
8

Sample Output

1
3
2

HINT

 

 对于第三个例子8,可以分为3+5,3和5的最大除数都是1,所以答案是2

C++版本一

题解:

任意一个大于2的偶数都能被拆分成两个素数的和。同时任意一个大于5的奇数都能被拆分成3个素数的和,一个为3,剩下的是偶数,按照前面的拆分即可。同时对于奇数还要考虑n-2为素数时,个数为2而不是3.

验证大素数则可以用米勒罗宾素数测试。

#include<bits/stdc++.h>
using namespace std;
#define ll long long

ll mod_mul(ll a, ll b, ll n) {
    ll res = 0;
    while(b) {
        if(b&1)    res = (res + a) % n;
        a = (a + a) % n;
        b >>= 1;
    }
    return res;
}
ll mod_exp(ll a, ll b, ll n) {
    ll res = 1;
    while(b) {
        if(b&1)    res = mod_mul(res, a, n);
        a = mod_mul(a, a, n);
        b >>= 1;
    }
    return res;
}
bool miller_rabin(ll n) {
    if(n == 2 || n == 3 || n == 5 || n == 7 || n == 11)    return true;
    if(n == 1 || !(n%2) || !(n%3) || !(n%5) || !(n%7) || !(n%11))    return false;
    ll x, pre, u;
    int i, j, k = 0;
    u = n - 1;  
    while(!(u&1)) {    
        k++; u >>= 1;
    }
    srand((ll)time(0));
    for(i = 0; i < 20; ++i) {    
        x = rand()%(n-2) + 2;   
        if((x%n) == 0)    continue;

        x = mod_exp(x, u, n);    
        pre = x;
        for(j = 0; j < k; ++j) {
            x = mod_mul(x, x, n);
            if(x == 1 && pre != 1 && pre != n-1)    return false;   
            pre = x;
        }
        if(x != 1)    return false; 
    }
    return true;
}

int main() {
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int t;
	scanf("%d",&t);
	ll n;
	while(t--) {
		scanf("%lld",&n);
		if(n%2 == 0) {
			if(n == 2) printf("1\n");
			else printf("2\n");
		}
		else {
			if(miller_rabin(n)) printf("1\n");
			else if(miller_rabin(n-2)) printf("2\n");
			else printf("3\n");
		}
	}
}

C++版本二

哥德巴赫猜想

大于二的偶数可以分解为两个素数之和;

大于七的奇数可以分解为三个素数之和;(是一定可以分解成三个素数之和,也有可能分解成两个)分解成两个必然有一个是2,其他就是至少三个。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <string.h>
#include <cmath>
#include <queue>
using namespace std;
typedef long long ll;
const int N=10000;
ll t,n,m;
int a[N];
bool prime(int x){
     for(int i=2;i<=sqrt(x);i++)
        if(x%i==0)
        return 0;
     return 1;
 
}
int main()
{
    scanf("%lld",&t);
    while(t--){
        scanf("%lld",&n);
        if(prime(n)||n==1||n==2||n==3)
             cout << 1 << endl;
        else if(n%2==0||prime(n-2))
             cout << 2 << endl;
        else
             cout << 3 << endl;
    }
    //cout << "Hello world!" << endl;
    return 0;
}