説明
既知のnは整数B1、B2、...、BN
整数K(K <N)。
必要に応じてそれぞれ使用可能の範囲でnは整数の整数kを加えます。
例えば、N = 4、K = 3,4の整数で、それぞれ、利用可能な3,7,12,19、それらのすべての組み合わせであるときである:
3 + 7 + 12 = 223 + 7 + 19 = 297 + 12 + 19 = 383 + 12 + 19 = 34。
今、私たちは種の合計数を計算するように依頼し、素数です。
+ 7 3 + 19 = 29:たとえば、実施形態は、一つだけ、そして素数です。
入力
最初の二つの整数の行:N、K(1 <= N <= 20、K <n)の
2行目のnは整数:X1、X2、...、XN (1 <= XI <= 5000000)
出力
整数(プログラムの条件を満足する数値)。
最終ACコード:
#include <cstdioを> 整数 K、N-、NUM、P [ 25 ]、A [ 25 ]; // P []を選択した予約番号の配列の配列 BOOL VIS [ 22は ] = { falseに}; BOOL isPrime(INT N-){ IF(N < 2)リターン falseに、 のために(INT I = 2、I *はI <= N; I ++)IF(N-%のI == 0)リターン falseに、 リターン trueに; } 無効 DFS(int型のインデックス){ IFを(インデックス== K +1 ){ int型 Iを、和= 0 。 以下のために(iは= 1 ; I <= K; I ++)合計+ = [P [I]]。 もし(isPrime(合計))NUM ++ ; リターン; } のためには、(INTは iがインデックスを=; I <= N; I ++ ){ 場合(VIS [I] && P [index-!1 ] < I){ P [インデックス] = I。 VIS [i]は = 真; DFS(インデックス + 1 )。 VIS [I] = 偽 ; } } } int型のmain(){ int型I。 P [ 0 ] = 0 ; 一方、(〜のscanf(" %D%D "、&N&K)){ ためには、(iは= 1 ; I <= N; I ++)のscanf(" %dの"、および[I])。 NUM = 0 ; DFS(1 )。 printf(" %dの\ n " 、NUM)。 } 戻り 0 。 }
概要:初めにマップレコードの使用は和と判断されているので、コード、ビッグデータのタイムアウトについての心配を書いて、それ以降のテストでは、構成要素の同じ合計、合計はなく、同じであるとき、ここでは2例と見なさことを発見したとき。次に、フォームがint A = SQRT(b)の場合、次に0の値が正しいアプローチ得られるであろう=(INT)SQRT(b)は、intです。
(私はこの解決策は何度も見てきたことを認めるものの、なぜは自分自身にそれを毎回覚えていない?)その後Baiduは、いっそのソリューションを参照してください
以下のように自身が、後に、この考え方に従うことをもう一度書きました:
#include <cstdioを> 整数 N、K、NUM、[ 25 ]。 BOOL isPrime(int型N){ 場合(N < 2)リターン 偽。 以下のために(INT iが= 2 ; iが* I <= N; I ++)場合(N%I == 0)リターン 偽。 返す 真; } ボイド DFS(int型のインデックス、INT CNT、INT 合計){ 場合(CNT == K){ // 说明得到了K个数 場合(isPrime(SUM))NUM ++ ; リターン; } IF(インデックス== N-CNT ||> K)のリターン ; // 説明判断超える DFS(インデックス + 1、CNT +を1、A + SUM [インデックス]); / / 選択インデックス DFS(インデックス + 1、CNT、SUM); // ない選択されたインデックス } INT (メイン){ int型I; ながら(〜scanfの(" %D%D "、およびN-、&)K){ ため(I = 0 ; I <N-; I ++)scanfの(" %のD "、&[I])。 NUM = 0 ; DFS(0、0、0 ); printf(" %dの\ n " 、NUM)。 } 戻り 0 。 }
ああ、非常に単純な、しかし、はるかに高速.........