本蒟蒻第一篇题解

· · 题解

使用算法:

DFS

核心:

我们知道,所有素数除了 2 外都是奇数,而且两个奇数的和是偶数。

所以:

  1. 这个素数不为 2 ,那么:这个素数加减想成为另一个素数 ,只能加减 2。

  2. 这个素数等于 2,那么:这个素数加减想成为另一个素数 ,只能加上另一个不为 2 的素数。

原理都知道啦题目还不简单嘛。

所以,看看下面比较长的代码吧。

#include <iostream> 
#include <cmath>
/*
听我一句忠告:
不要用bits,不要用bits,不要用bits! 
*/
using namespace std;//名字空间 
long long a,b;
bool flag=false;
long long f[100];//用f存答案 
bool prime(long long x)//普通筛,懒得写线性筛 
{
    if(x==0||x==1)return false;//1||0不是素数 
    if(x%2==0&&x!=2)return false;//非2偶数更不是 
    if(x==2)return true;//2是素数 
    for(int i=3; i<=sqrt(x); i+=2)
    /*
    为什么要开根?
    很简单:
    16是不是素数?
    16=2^4
    开根相当于将它的质因数完全一样的分成两份,连它的质因数的一半
    都不是素数那它会是素数吗? 
    至于i+=2嘛,偶数直接跳过 
    */ 
        if(x%i==0)return false;//根据素数的定义来判断它是否是素数 
    return true;// 剩下的都是啦 
}
void dfs(long long x,long long y,int step)
//用x代表A素数,用y代表B素数,用step代表素数个数 
{
    if(flag)return;//找到了直接走 
    if(prime(abs(x-y)))//abs是必要的,如果去掉,会判断一个负数是不是素数 
    {
        cout<<step+1<<endl<<a<<" ";//上次是step+2,这次是step+1 
        for(int i=1; i<=step-1; i++)//去掉尾 
            cout<<f[i]<<" ";
        cout<<b;
        flag=true;//打上标记 
        return;
    }
    if(x!=2)//分为两种情况:1.两个奇数;2.一奇一偶 
        for(int i=1; i<=3; i++)
        {
            /*
            关于prime(x +/- 2):
            我们知道,所有素数除了2外都是奇数,而且奇+奇=偶
            所以:
            1.这个prime不为2,那么:这个prime加减想成为另一个prime,只能加减2
            2.这个prime=2,那么:这个prime加减想成为另一个prime,只能加上另一个不为 2的素数
            */ 
            if(i==1&&prime(x-2))f[step]=2,dfs(2,y,step+1);
            if(i==2&&prime(x-2))f[step]=x-2,dfs(x-2,y,step+1);
            if(i==3&&prime(x+2))f[step]=x+2,dfs(x+2,y,step+1);
        }
    else if(prime(y+2))//一奇一偶的情况 
        f[step]=y+2,dfs(y+2,y,step+1);//一样的道理 
}
signed main()
{
    cin>>a>>b;
    if(prime(abs(a-b)))//特判,如果AB直接可达,那么直接输出 
    {
        cout<<2<<endl<<a<<" "<<b;
        return 0;
    }
    dfs(a,b,1);//出发 
    if(!flag)//判断不可能 
        cout<<"-1"; 
    return 0;//完结撒花 
}