1. 程式人生 > 其它 >牛客挑戰賽 53 B

牛客挑戰賽 53 B

題目描述

你需要找到一個序列 \(A_1, A_2 \dots A_i\dots A_m\)
並且每個 $A_i 都為質數或者 \({1}\) 或者 \({0}\) 使得

\(\sum_{i = 1}^{m}{A_i}\)

對於每個詢問,你需要找到最小的 \({m}\)

資料保證題目有解。

特別的是,如果 \({s=0}\) 那麼你也至少需要一個 \({0}\) 來填滿它。

資料範圍

\(1 \leq s\leq 10^7\)

solution

如果 \(s\) 是個偶數,根據哥德巴赫猜想,它一定可以分解為兩個質數的和的形式。

如果是奇數的話就有兩種可能,一個是它可以由 \(2\) 和另一個質數相加,這種直接 \(check(n - 2)\)

就好。

另一種是把奇數 \(-1\) 變為偶數,在將這個偶數按照上面分解。

線篩預處理個質數就好了。

code

/*
work by:Ariel_
Sorce:
Knowledge:
Time:
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#define rg register
using namespace std;
const int MAXN = 1e7 + 5;
int read(){
    int x = 0,f = 1; char c = getchar();
    while(c < '0'||c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') {x = x*10 + c - '0'; c = getchar();}
    return x*f;
}
int tot, pre[MAXN];
bool vis[MAXN];
void Pre() {
   for(int i = 2; i <= MAXN; i++) {
      if(vis[i] == 0) pre[tot++] = i;
       for(int j = 0; j <= tot, i * pre[j] <= MAXN; j++){
    	  vis[pre[j] * i] = 1;
    	  if (i % pre[j] == 0)break;
		}
	}
}
signed main() {
	int T = read();
	Pre();
	while(T--) {
	  int x = read();
	  if(x == 0) {cout<<"1\n0 = 0\n";continue;}
	  if(x == 1) {cout<<"1\n1 = 1\n";continue;}
	  if(!vis[x]){cout<<"1\n"<<x<<" = "<<x<<"\n";continue;}
	  int opt = 1;
 	  if(x & 1) {
 	  	 int fag = 0, z, w;
 	  	 if(!vis[x - 2]) {
 	  	    cout<<"2\n";
		    cout<<"2 + "<<x - 2<<" = "<<x<<"\n";
			continue;	 
		 }
	     cout<<"3\n"<<"1 + "; 
		 x--, opt = 0;
	  }
	  else cout<<"2\n";
	  for (int i = 3; i < x; i++) 
	    if (!vis[i] && !vis[x - i]){printf("%d + %d",  i,  x - i); break;}
 	  if(opt == 0) printf(" = %d\n", x + 1);
 	  else printf(" = %d\n", x);
	}
	return 0;
}