#include<iostream>usingnamespace std;intmain(){int N;
cin >> N;if(N %2==0){
cout << N /2<< endl;for(int i =0;i < N /2;i++)
cout <<2<<" ";return0;}
N = N -3;
cout << N /2+1<< endl;for(int i =0;i < N /2;i++)
cout <<2<<" ";
cout <<3;return0;}
以下为大冤种,经历:
先用埃式筛把【0,n】区间的素数全都筛到一个数组里。
再使用深搜找到所有复核质数分解的解中,分解的个数最多的。
#include<iostream>#include<math.h>#include<vector>#include<algorithm>usingnamespace std;int prime[500];//可分解素数的集合int f =0;//分解素数的个数;typedeflonglong ll;//bool is_prime[500];//是否为素数(0,b)bool is_primesmall[500];//是否为素数(0,b^0.5)
vector<vector <int>> obj;//chushi化的是20的矩阵
vector<int> temp;int cc =0;//记录现在有几项分解成功的值;voidsegment(int b){
is_prime[0]=false;
is_prime[1]=false;for(int i =0;(ll)i * i < b;i++) is_primesmall[i]=true;for(int i =0;i < b;i++) is_prime[i]=true;for(int i =2;(ll)i * i < b;i++){if(is_primesmall[i]){for(int j =2* i;(ll)j * j < b;j += i) is_primesmall[j]=false;//2LL可以理解为2*1LL,其中max可以直接在第二个数组中定位出第一个数组中素数的最小倍数for(ll j =max(2LL,ll(i -1)/ i)* i;j < b;j += i){
is_prime[j]=false;}}}for(int i=2;i<=b;i++)if(is_prime[i]){
prime[f++]= i;}return;}voiddoubletwo(int n){
cout << n /2<< endl;for(int i =1;i < n /2;i++)
cout <<2<<" ";
cout <<2;return;}voiddfs(int n,int index,int sum_num, vector<int>& temp){if(sum_num > n)return;if(sum_num == n){
obj.push_back(temp);sort(obj.begin(), obj.end());
obj.erase(unique(obj.begin(), obj.end()), obj.end());}if(index <f){// sum == n 找到了这样的一组数字
temp.push_back(prime[index]);dfs(n, index , sum_num + prime[index], temp);
temp.pop_back();dfs(n, index +1, sum_num, temp);}}intmain(){int n;
cin >> n;if(n %2==0){doubletwo(n);return0;}segment(n);dfs(n,0,0, temp);int sum =0;int i_um =0;for(int i =0; i < obj.size(); i++){if(sum < obj[i].size()){
sum = obj[i].size();
i_um = i;}}
cout << sum << endl;for(int j =0;j < obj[i_um].size();j++)
cout << obj[i_um][j]<<" ";return0;}