蓝桥杯专训(c++),简单数论问题

1、

这个题目其实就是一个排列组合的问题。我们反着来推结论:所有的情况-不会引发越狱的情况=会发生越狱的情况。也就是 m的n次方- m * (m-1)^(n - 1);

#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>

using namespace std;

#define ll long long

const int mod = 100003;

ll n ,m;

ll h(ll a ,ll b)//快速幂
{
	ll res = 1 % mod;
	while (b)
	{
		if (b & 1) res = res * a % mod;
    a = a * a % mod;
		b >>= 1;
		
	}
	
	return res;
}

int main()
{
	cin >> m >> n;
	
	cout << (h(m ,n) - m * h(m - 1 ,n - 1) % mod + mod) % mod << endl;//根据结论算出结果
	
	return 0;
} 

2、

 我们需要知道一个定理:

任何一个数N都可以分解成其质因子的次方积:N = (p1^x1)(p2^x2)(p3^x3)…(pk^xk)

那么N的约数个数=(x1+1)(x2+1)(x3+1)…(xk+1);

知道这个定理后,我们就可以简单估算一下s100可能是多少,比如:2^4 * 3^4 * 5^3 = 162000

那么结果一定是小于等于162000的,所以我们可以直接暴力枚举解决这个问题。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>

using namespace std;

bool check(int x)
{
	int res = 0;
	for (int i = 1 ;i * i <= x ;i ++)
	{
		if (x % i == 0)
		{
			if (i * i != x) res += 2;
			else
				res ++;
		}
	}
	
	if (res == 100) return true;
	else
		return false;
}

int main()
{
	for (int i = 1 ;i ;i ++)
	{
		if (check(i)) 
		{
			cout << i;
			break;
		}
	}
	return 0;
}

3、

 由等差数列的基本性质,an = a1 + (n - 1) * d,我们可以很清楚的得到等差数列的两两之差一定是d的倍数。那么我们只需要将所有项的差取出并且求它们的最大公约数,那么就可以得到d的结果,,然后利用公式(an - a1) / d + 1 = n就可以得到结果:

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>

using namespace std;

#define N 1000100

int n ,a[N] ,ans = 0;

int gcd(int a ,int b)
{
    return b ? gcd(b ,a % b) : a;
}

int main()
{
    cin >> n;
    
    for (int i = 1 ;i <= n ;i ++) cin >> a[i];
    
    sort(a + 1 ,a + n + 1);
    
    int d = a[2] - a[1];
    for (int i = 3 ;i <= n ;i ++)
    {
        d = gcd(d ,a[i] - a[1]);
    }
    
    if (d == 0) cout << n;
    else
        cout << (a[n] - a[1]) / d + 1;
    return 0;
}

4、

 这个题目比较复杂,要用到更相减损术;

#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

#define ll long long
#define N 150

ll f[N];

ll gcd(ll a ,ll b)
{
    return b ? gcd(b ,a % b) : a;
}

struct node{
    ll x ,y;
}q[N];

ll jian(ll a ,ll b)
{
    if (a < b) swap(a ,b);
    if (b == 1) return a;
    return jian(b ,a / b);
}

int main()
{
    int n;
    cin >> n;
    for (int i = 1 ;i <= n ;i ++) cin >> f[i];
    
    sort(f + 1 ,f + 1 + n);
    
    int idx = 0;
    for (int i = 2 ;i <= n ;i ++)
    {
        if (f[i] != f[i - 1])
        {
            q[++ idx] = {f[1] ,f[i]};
        }
    }
    
    for (int i = 1 ;i <= idx ;i ++)
    {
        ll t = gcd(q[i].x ,q[i].y);
        q[i] = {q[i].x / t ,q[i].y / t};
    }
    
    ll mu = q[1].x ,zi = q[1].y;
    for (int i = 2 ;i <= idx ;i ++)
    {
        mu = jian(mu ,q[i].x);
        zi = jian(zi ,q[i].y);
    }
    
    
    printf("%lld/%lld" ,zi ,mu);
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值