最大公约数、素数、约数、最小公倍数

最大公约数和最小公倍数问题
Description
输入2个正整数x0​,y0​(2≤x0​<100000,2≤y0​<=1000000),求出满足下列条件的P,Q的个数

条件:

P,Q是正整数
要求P,Q以x0​为最大公约数,以y0​为最小公倍数.
试求:满足条件的所有可能的2个正整数的个数.

Input
2个正整数x0​,y0​

Output
1个数,表示求出满足条件的P,Q的个数

Sample Input
3 60
Sample Output
4
Hint
P,Q有4种

1、3,60
2、15,12
3、12,15
4、60,3

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int x,y,a,b,gs=0,i,j;
    cin>>x>>y;
    for(i=1;i<=y;i++)
    {
        j=y*x/i;
        if(__gcd(i,j)==x&&i*j/__gcd(i,j)==y)
        {
            gs++;
        }
    }
    cout<<gs<<endl;
    return 0;
}

最大约数和
Description
选取和不超过S的若干个不同的正整数,使得所有数的约数(不含它本身)之和最大。

Input
输入一个正整数S。

Output
输出最大的约数之和。

Sample Input
11
Sample Output
9
Hint
样例说明

取数字4和6,可以得到最大值(1+2)+(1+2+3)=9。

数据规模

S<=1000

#include<bits/stdc++.h>
using namespace std;
int a[1001],dp[1001];
int ys(int x);
int main()
{
    int i,n,j;
    cin>>n;
    for(i=1;i<=n;i++)
    {
        a[i]=ys(i);
    }
    for(i=1;i<=n;i++)
    {
        for(j=n;j>=i;j--)
        {
            dp[j]=max(dp[j-i]+a[i],dp[j]);
        }
    }
    cout<<dp[n]<<endl;
    return 0;
}
int ys(int x)
{
    int i,ans=0;
    for(i=1;i<x;i++)
    {
        if(x%i==0)
        {
            ans+=i;
        }
    }
    return ans;
}

约数研究
Description
科学家们在Samuel星球上的探险得到了丰富的能源储备,这使得空间站中大型计算机“Samuel II”的长时间运算成为了可能。由于在去年一年的辛苦工作取得了不错的成绩,小联被允许用“Samuel II”进行数学研究。

小联最近在研究和约数有关的问题,他统计每个正数N的约数的个数,并以f(N)来表示。例如12的约数有1、2、3、4、6、12。因此f(12)=6。下表给出了一些f(N)的取值:

f(n)表示n的约数个数,现在给出n,要求求出f(1)到f(n)的总和。

Input
输入一行,一个整数n

Output
输出一个整数,表示总和

Sample Input
3
Sample Output
5
Hint
【数据范围】

20% N<=5000

100% N<=1000000

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,i,ans=0;
    cin>>n;
    for(i=1;i<=n;i++)
    {
        ans+=n/i;
    }
    cout<<ans<<endl;
    return 0;
}

最强素数
Description
小李在你帮助之下轻松战胜了他的同学们,于是满怀恶意的同学出了一个题目来为难小李,作为小李神一样的队友,你又要出力了。素数41能写成连续6个素数之和:41=2+3+5+7+11+13。现在要求n以内的素数中,能表示为最多连续素数之和的那个数,如果有多个答案,请输出最大的那个素数。

Input
仅一行,一个整数n,1<=n<=1000000

Output
输出就一个整数,为所求的能表示为最多连续素数和的那个素数。

Sample Input
100
Sample Output
41

#include<bits/stdc++.h>
using namespace std;
bool bj[10000001];
int gs,ss[10000001],n;
void csh()
{
    int i,j;
    bj[1]=bj[0]=true;
    for(i=2;i<=n;i++)
    {
        if(!bj[i])
        {
            for(j=i+i;j<=n;j+=i)
            {
                bj[j]=true;
            }
            gs++;
            ss[gs]=i;
        }
    }
}
int main()
{
    int cd,ans,t,i,j,ls,lscd;
    cd=ans=0;
    cin>>n;
    csh();
    for(i=1;i<=gs;i++)
    {
        ls=lscd=0;
        for(j=i;j<=gs;j++)
        {
            ls+=ss[j];
            lscd++;
            if(n<ls)
            {
                break;
            }
            else
            {
                if(!bj[ls])
                {
                    if(lscd>=cd)
                    {
                        cd=lscd;
                        ans=ls;
                    }
                }
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

素数分解
Description
素数,又称质数,是指除 1 和其自身之外,没有其他约数的正整数。例如 2、3、5、13 都是质 数,而 4、9、12、18 则不是。

  虽然素数不能分解成除 1 和其自身之外整数的乘积,但却可以分解成更多素数的和。

  你需要编程 求出一个正整数最多能分解成多少个互不相同的素数的和。

  例如,21 = 2 + 19是21的合法分解方法。21 = 2 + 3 + 5 + 11则是分解为最多素数的方法。

Input
n (10≤n≤200)。

Output
n 最多能分解成多少个不同的素数的和。

Sample Input
21

128
Sample Output
4

9

#include<bits/stdc++.h>
using namespace std;
bool ss(int x);
int ans,n,gs,a[201];
void csh();
void dfs(int qm,int cd,int x);
int main()
{
    cin>>n;
    csh();
    dfs(0,0,0);
    cout<<ans-1<<endl;
    return 0;
}
bool ss(int x)
{
    int i;
    if(x==2)
    {
        return true;
    }
    if(x<3)
    {
        return false;
    }
    for(i=2;i<=sqrt(x);i++)
    {
        if(x%i==0)
        {
            return false;
        }
    }
    return true;
}
void dfs(int x,int s,int he)
{
    if(s==n)
    {
        ans=max(ans,he);
        return;
    }
    if(s>n)
    {
        return;
    }
    if(x>=gs)
    {
        return;
    }
    dfs(x+1,s+a[x],he+1);
    dfs(x+1,s,he);
}
void csh()
{
    int i;
    for(i=2;i<=200;i++)
    {
        if(ss(i))
        {
            gs++;
            a[gs]=i;
        }
    }
}

连续非素数的最长度
Description
给出一个正整数n(2≤n≤1000000),例如n=30,在1,2,3,……30中,连续的非素数有
4 长度为1
6 长度为1
8 9 10 长度为3
12 长度为1
14 15 16 长度为3
18 长度为1
20 21 22 长度为3
24 25 26 27 28 长度为5
30 长度为1
其中,最大长度为5,即有连续的5个非素数。
Input
一个整数n。

Output
一个整数,即连续非素数最大长度。

Sample Input
12
Sample Output
3

#include<bits/stdc++.h>
using namespace std;
bool ss(int x);
int main()
{
    int n,i,gs,mx;
    cin>>n;
    if(n==1)
    {
        cout<<1<<endl;
        return 0;
    }
    gs=mx=0;
    for(i=1;i<=n;i++)
    {
        if(!ss(i))
        {
            gs++;
            mx=max(mx,gs);
        }
        else
        {

            gs=0;
        }
    }
    cout<<mx<<endl;

    return 0;
}

bool ss(int x)
{
    int i;
    if(x==2)
    {
        return true;
    }
    if(x<3)
    {
        return false;
    }
    for(i=2;i<=sqrt(x);i++)
    {
        if(x%i==0)
        {
            return false;
        }
    }
    return true;
}

最大素数
Description
给出一个整数n,求小于等于n的最大素数;

Input
输入包含多组测试案例;每个测试案例一个整数n,n大于等于2,小于等于1e7;

Output
输出小于等于n的最大素数;

Sample Input
2
3
4
100
Sample Output
2
3
3
97

#include<bits/stdc++.h>
using namespace std;
bool bj[10000001];
bool ss(int x);
int main()
{
    int n,i,j;
    while(cin>>n)
    {

    for(i=1;i<=10000000;i++)
    {
        bj[i]=true;
    }
    for(i=2;i<10000000;i++)
    {
        if(bj[i])
        {
            bj[i]=true;
            for(j=i+i;j<=n;j+=i)
            {
                bj[j]=false;
            }
        }
    }
    int gs;
    for(i=n;i>=1;i--)
    {
        if(bj[i])
        {
            gs=i;
            break;
        }
    }
    cout<<gs<<endl;
    }
    return 0;
}
bool ss(int x)
{
    int i;
    if(x==2)
    {
        return true;
    }
    if(x<3)
    {
        return false;
    }
    for(i=2;i<=sqrt(x);i++)
    {
        if(x%i==0)
        {
            return false;
        }
    }
    return true;
}

【基础】圆环上求素数II
Description
将0,1,2,……9共10个数打乱次序后排成一圈,给出一个取数长度L(1<=L<=5),然后从1开始按顺时针方向连续取L个数字,拼成一个长度为L位(最高位为0的L-1位数不算)的数。此时共有9个数,然后输出这9个数中的素数。

Input
第一行为空格隔开的10个数字, 第二行为一个整数L。

Output
全部满足条件的素数,中间用’,'隔开。

Sample Input
8 9 1 0 2 3 5 4 7 6
3
Sample Output
547

#include<bits/stdc++.h>
using namespace std;
int a[21],b[11],sss[11];
bool ss(int x);
int main()
{
    int i,l,gs=0,j;
    for(i=1;i<=10;i++)
    {
        cin>>a[i];
        a[i+10]=a[i];
    }
    cin>>l;
    for(i=1;i<=10;i++)
    {
        if(a[i]!=0)
        {
            b[i]=0;
            for(j=i;j<=i+l-1;j++)
            {
                b[i]=b[i]*10+a[j];
            }
            if(ss(b[i]))
            {
                gs++;
                sss[gs]=b[i];
            }
        }
    }
    if(gs==0)
    {
        return 0;
    }
    for(i=1;i<gs;i++)
    {
        cout<<sss[i]<<',';
    }
    cout<<sss[gs]<<endl;
    return 0;
}
bool ss(int x)
{
    int i;
    if(x==2)
    {
        return true;
    }
    if(x<3)
    {
        return false;
    }
    for(i=2;i<=sqrt(x);i++)
    {
        if(x%i==0)
        {
            return false;
        }
    }
    return true;
}

【基础】求无暇素数
Description
一个两位整数A本身是素数,若将其个位数字与十位数字交换,得到一个新的两位数B,而B也是素数,我们则称A为无暇素数。 例如:31是素数,个位数字与十位数字交换后得到13,也是素数。所以31是无暇素数。 问题: 给出一个数字字符串(即字串中的字符全部由数字组成),相邻两个数字可组成一个两位数,求出其所有组成的无暇素数。

Input
一个数字字符串(长度<=20),以“%”结束。

Output
全部的无暇素数,之间用一个逗号隔开。

Sample Input
321314%
Sample Output
13,31

#include<bits/stdc++.h>
using namespace std;
int aa[101];
bool ss(int x);
int main()
{
    string s;
    int a,i,gs;
    cin>>s;
    a=s.size()-2;
    gs=0;
    for(i=0;i<a;i++)
    {
        if(ss((s[i]-'0')*10+(s[i+1]-'0'))&&ss((s[i+1]-'0')*10+(s[i]-'0')))
        {
            gs++;
            aa[gs]=(s[i]-'0')*10+(s[i+1]-'0');
        }
    }
    if(gs==0)
    {
        return 0;
    }
    cout<<aa[1];
    for(i=2;i<=gs;i++)
    {
        cout<<','<<aa[i];
    }
    cout<<endl;
    return 0;
}
bool ss(int x)
{
    int i;
    if(x==2)
    {
        return true;
    }
    if(x<3)
    {
        return false;
    }
    for(i=2;i<=sqrt(x);i++)
    {
        if(x%i==0)
        {
            return false;
        }
    }
    return true;
}

【模板】线性筛素数
Description
如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内)

Input
第一行包含两个正整数N、M,分别表示查询的范围和查询的个数。

接下来M行每行包含一个不小于1且不大于N的整数,即询问该数是否为质数。

对于30%的数据:N<=10000,M<=10000

对于100%的数据:N<=10000000,M<=100000

Output
输出包含M行,每行为Yes或No,即依次为每一个询问的结果。

Sample Input
100 5
2
3
4
91
97
Sample Output
Yes
Yes
No
No
Yes
Hint
样例说明:

N=100,说明接下来的询问数均不大于100且不小于1。

所以2、3、97为质数,4、91非质数。

故依次输出Yes、Yes、No、No、Yes。

#include<bits/stdc++.h>
using namespace std;
bool bj[10000001]={true,true};
bool ss(int x);
int main()
{
    int n,i,j,m,k,t;
    cin>>t>>m;
    for(i=2;i<=10000000;i++)
    {
        if(!bj[i])
        {
            for(j=i+i;j<=t;j+=i)
            {
                bj[j]=true;
            }
        }
    }
    for(k=1;k<=m;k++)
    {
        scanf("%d",&n);
        if(!bj[n])
        {
            printf("Yes\n");
        }
        else
        {
            printf("No\n");
        }
    }
    return 0;
}
bool ss(int x)
{
    int i;
    if(x==2)
    {
        return true;
    }
    if(x<3)
    {
        return false;
    }
    for(i=2;i<=sqrt(x);i++)
    {
        if(x%i==0)
        {
            return false;
        }
    }
    return true;
}

素数个数
Description
求 1,2,⋯,N 中素数的个数。

Input
一行一个整数 N

Output
一行一个整数,表示素数的个数。

Sample Input
10
Sample Output
4
Hint
对于 40% 的数据,≤N≤10^6。

对于 100% 的数据, 1≤N≤10^7。

#include<bits/stdc++.h>
using namespace std;
bool bj[10000001];
bool ss(int x);
int main()
{
    int n,i,j;
    cin>>n;
    for(i=3;i<=10000000;i++)
    {
        bj[i]=true;
    }
    for(i=2;i<10000000;i++)
    {
        if(bj[i])
        {
            bj[i]=true;
            for(j=i+i;j<=n;j+=i)
            {
                bj[j]=false;
            }
        }
    }
    int gs=0;
    for(i=2;i<=n;i++)
    {
        if(bj[i])
        {
            gs++;
        }
    }
    cout<<gs<<endl;
    return 0;
}
bool ss(int x)
{
    int i;
    if(x==2)
    {
        return true;
    }
    if(x<3)
    {
        return false;
    }
    for(i=2;i<=sqrt(x);i++)
    {
        if(x%i==0)
        {
            return false;
        }
    }
    return true;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值