迟来的18.12.11的题解

18.12.11题解

 

素数个数(prime)

题目描述求{1,2,...,N} 中素数的个数。

输入

 1 个整数 N

 输出

1 个整数,表示素数的个数。

 样例输入

10

样例输出

 4

提示

对于 40% 的数据,1N106

对于 80% 的数据,1N10 7

对于 100% 的数据,1 N <6*10 7

 

参考代码

#include <cassert>

#include <cstdio>

#include <cstring>

const int N = 100000000;

bool isPrime[N+1];   //数组较大开在外面  用来记录是否是素数

int primeCount, primes[5761455];

int main() {

   freopen("prime.in","r",stdin); 

   freopen("prime.out","w",stdout);

    int n; 

    assert(scanf("%d", &n) == 1);  //判断输入是否符合规定

    assert(1 <= n && n <= N);

    memset(isPrime, true, sizeof(isPrime));   //将初始定义为1(即假设他们都是素数)

    primeCount = 0;

for (int i = 2; i <= n; ++ i)

{

        if (isPrime[i])

{

            primes[primeCount ++] = i;

        }

        for (int j = 0; j < primeCount && i * primes[j] <= n; ++ j)

 {

            isPrime[i * primes[j]] = false; //两个数相乘后得到的数肯定不是素数标记

            if (i % primes[j] == 0)  //保证i>j 避免重复运算

{

                break;

            }

        }

    }

    printf("%d\n", primeCount);

    return 0;

}

 

自己的代码

 

#include<cstdio>

#include<cstring>

using namespace std;

bool mark[6000000];

int main()

{

       int n,j,k=0,h;

       scanf("%d",&n);

       memset(mark,true,sizeof(mark));

       for(int i=2;i<=n;i++)

       {

              for(j=2;i * j <= n && i>=j;j++)

              {

                     mark[i*j] = false;

                     }    

       }

       for(int i = 2;i <= n;i++)

              if( mark[i] == 1)

                     k++;

       printf("%d",k);

       return 0;

 }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

21103: 数学欧拉函数(phi)

题目描述

对正整数nn的欧拉函数(即φ(N))是少于或等于n的数中与n互质的数的数目。例如φ(8)=4,因为1,3,5,7均和8互质。

输入

一行一个整数N

输出

一行一个整数φ(N)

样例输入

8

样例输出

4

提示

 

 

对于70%的数据,有N<=1000

 

对于100%的数据,有N<=231-1

 

参考代码

#include<iostream>

#include<cstring>

using namespace std;

long long n,ans;

int main()

{

    cin>>n;

    ans=n;

    int i=1;

    while(n!=1)

    {

        i++;

        if(n%i==0)

        {

            ans=ans/i*(i-1);

            n=n/i;

        }

        while(n%i==0) n=n/i;

    }

    cout<<ans;

    return 0;

}

 

 

自己的代码

#include<cstdio>

using namespace std;

long long n,m;

int main()

{

       scanf("%lld",&n);

       m=n;

       int i=1;

       while(n != 1)

       {

              i++;    //每循环一次就加1

              if(n % i == 0)   //可以被除的开的话

              {

                     m = m / i * (i-1); 

                     n /= i;

              }

              while(n%i==0) n=n/i;

       }       //这里其实是一个递归

       printf("%lld",m);

       return 0;

}

 

公式:

就是这个公式

Euler(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

31631: NOIP 2012 同余方程(mod)

题目描述

求关于x的同余方程ax ≡ 1 (mod b)的最小正整数解。

输入

输入只有一行,包含两个正整数ab,用一个空格隔开。

输出

输出只有一行,包含一个正整数x0,即最小正整数解。输入数据保证一定有解。

 

样例输入

3 10

样例输出

7

提示

对于40%的数据,2 ≤b≤ 1,000

 

对于60%的数据,2 ≤b≤ 50,000,000

 

对于100%的数据,2 ≤ab≤ 2,000,000,000

 

参考代码

#include<iostream>

using namespace std;

long long a,b,x,y;

void exgcd(long long a,long long b,long long &x,long long &y)

{

    if(b==0)

    {

        x=1;

        y=0;

        return;

    }

    exgcd(b,a%b,x,y);

    int z=x;

    x=y;

    y=z-y*(a/b);

}

int main()

{

  

    cin>>a>>b;

    exgcd(a,b,x,y);

    cout<<(x%b+b)%b<<endl;

}

 

自己的代码(也是学习来的)

#include<cstdio>

using namespace std;

long long a,b,x,y;

void exgcd(long long a,long long b,long long &x,long long &y)

{

    if(b==0)

    {

        x=1;

        y=0;

        return;

    }

    exgcd(b,a%b,x,y);

    int z=x;

    x=y;

    y=z-y*(a/b);

}

int main()

{

       scanf("%lld%lld",&a,&b);

       exgcd(a,b,x,y);

       printf("%lld",(x%b+b)%b)

 }

 

是扩展gcd的应用

猜你喜欢

转载自www.cnblogs.com/darlingroot/p/10123493.html
今日推荐