zoukankan      html  css  js  c++  java
  • 素数分组 哥德巴赫猜想

    题目描述

    最少把1~n 分成多少组,可以使得每组的数的和为素数

    输入

    有多组数据
    第一行是一个数T,表示数据组数
    每组数据共1 行,为正整数n

    输出

    有T 行,每行为该情况的最少组数,无法分组时,输出-1

    样例输入

    1 2

    样例输出

    1
     
     
    哥德巴赫猜想裸题
    首先如果sum(n)是偶数,即两个素数之和,writeln(2)
    如果sum(n)是奇数,那么分类讨论,如果sum(n)是质数,1即可
    如果不是素数
    check(sum(n)-2),如果是素数,就是3了
     
    关于证明:
    我们首先把1~n全部加起来,那么我们相当于把1~n分成了一组
    我们知道:任意一个偶数都可以表示为两个质数之和
    如果(∑n and 1)=0那么就是2个质数之和了
    否则,如果∑n不为偶数,我们还需要分类讨论,
    分类为,奇质数和非奇质数,奇质数好说,既然都是质数了,那么直接和就是一组,writeln(1)
    否则,我们对于这个非质数,我们拿这个数去减2
    2是唯一的偶质数,任意一个大于7的奇数可以表示为三个质数之和
    由数学归纳法,若2不在三个质数中,那么往大更不在。
    所以若减2之后不是质数writeln(3)即可,否则输出2即可。
    判断质数用miller-rabin,大大优化常数
    代码如下:
    {$inline on}
    var j,k,l,n,m,s,t:int64;
        b:boolean;
        i:longint;
        a:array[2..6] of integer=(3,5,7,13,19);
     
    const count=10;
          pri:array [0..10] of longint=(2,3,5,7,11,13,17,19,23,29,31);
     
    function multi(a,b,m:int64):int64;
    var ans:int64;
    begin
      ans:=0;
      a:=a mod m;
      while b<>0 do
        begin
          if (b and 1)=1 then
            begin
              ans:=(ans+a) mod m;
              dec(b);
            end;
          b:=b>>1;
          a:=(a+a) mod m;
        end;
      exit(ans);
    end;
     
    function gcd(x,y:int64):int64;
    begin
      if x mod y=0 then
        exit(y)
      else exit(gcd(y,x mod y));
    end;
     
    function quick_mod(a,b,m:int64):int64;
    var ans:int64;
    begin
            ans:=1; a:=a mod m;
            while b<>0 do
                    begin
                            if (b and 1)=1 then
                                    begin
                                            ans:=multi(ans,a,m);
                                            dec(b);
                                    end;
                            b:=b>>1;
                            a:=multi(a,a,m);
                    end;
            exit(ans);
    end;
     
    function prime(n:int64):boolean;
    var m,k,a,x,y:int64; i,j:longint;
    begin
      if n=2 then exit(true);
      if (n<2) or ((n and 1)=0) then exit(false);
      m:=n-1; k:=0;
      while (m and 1)=0 do
            begin
                    inc(k);
                    m:=m>>1;
            end;
      randomize;
      for i:=0 to count do
            begin
              a:=random(n) mod (n-1)+1;
              x:=quick_mod(a,m,n);
              y:=0;
              for j:=0 to k-1 do
                    begin
                            y:=multi(x,x,n);
                            if (y=1) and (x<>1) and (x<>n-1) then exit(false);
                            x:=y;
                    end;
              if y<>1 then exit(false);
            end;
      exit(true);
    end;
     
     
    procedure start; inline;
    var s:int64;
    begin
      s:=n*(n+1) shr 1;
      if n>=7 then
      if (s and 1)=0 then
        writeln('2')
      else
      if (prime(s)) then
        writeln('-1')
      else
      if prime(s-2) then
        writeln('2')
      else
        writeln('3');
      if (n<7) then
      begin
        if odd(n) then s:=n*(n shr 1+1) else s:=(n+1)*(n shr 1);
        m:=s-a[n];
        if m=0 then writeln('1') else writeln('2');
      end;
    end;
    
    procedure main; inline;
    begin
      read(t);
      for i:=1 to t do
      begin
        read(n);
        if (n=0)or(n=1) then writeln('-1')
        else start;
      end;
    end;
    
    begin
          main;
    end.
     
    View Code
     
     
     
  • 相关阅读:
    Silverlight C# 游戏开发:Flyer05与什么什么进行搏斗
    Silverlight C# 游戏开发:Flyer07做一个有开始的游戏
    Silverlight C# 游戏开发:面向对象在游戏中的实例(一)
    Silverlight C# 游戏开发:面向对象在游戏中的实例(二)
    Silverlight C# 游戏开发:Flyer06小小的改进让游戏更有趣
    linux网络命令ip\route\links回顾
    Google Style的C++编码规范
    TCP/IP协议和IP组播的视频传输
    Multicast server and client in Python
    用户profile中umask码的含义详解(默认是022)
  • 原文地址:https://www.cnblogs.com/logichandsome/p/4057278.html
Copyright © 2011-2022 走看看