牛客网 - Number

本文介绍了如何解决牛客网上关于Shuaishuai数的问题,这是一种由素数平方、立方和四次方之和组成的数。通过暴力求解方法,对不超过5000万的数进行计算,分析表明只需要考虑素数到7069的情况,避免了超时问题。代码实现包括三重循环和排序去重。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

We define Shuaishuai-Number as a number which is the sum of a prime square(平方), prime cube(立方), and prime fourth power(四次方).

The first four Shuaishuai numbers are:

How many Shuaishuai numbers in [1,n]? (1<=n<=50 000 000)

输入描述:

The input will consist of a integer n.

输出描述:

You should output how many Shuaishuai numbers in [1...n]

示例1

输入

28

输出

1

说明

There is only one Shuaishuai number

链接:https://ac.nowcoder.com/acm/problem/14615
来源:牛客网
 

分析:

本题n的数据范围是1到5000万,大约估计一下,用到的素数小于8000,因为8000的平方为6400万,7000的平方为4900万,无聊实测,素数打表到7070即可,即用到的素数最大为7069,所以本题直接暴力即可,有人打表到10的7次方级别,花了大约1500ms,而打表到7070只花了101ms。

打完素数表,直接三重循环,每当当前的素数的2 ~ 4次方大于所给的数时,就break,当然,打表也可以,不过本题是单个样例,不用担心超时,然后用sort一下,用unique去重即可。

有看到别人使用dfs,只不过要慢很多。

代码:

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 7070;
const int M = 5e7 + 7;
int vis[N];
int prime[N];
int tot;
int ans[M];
void init()
{
    for (int i = 2; i < N; i ++){
        if (!vis[i]){
            prime[tot ++] = i;
            for (int j = 2 * i; j < N; j += i)vis[j] = 1;
        }
    }
}
int solve(int n){
    int cnt  = 0;
    for (int i = 0; i < tot; i ++){
        ll x = prime[i] *prime[i];
        if (x >= n)break;
        for (int j = 0; j < tot; j ++){
            ll y = prime[j] * prime[j] * prime[j];
            if (y >= n)break;
            for (int k = 0; k < tot; k ++){
                ll z = prime[k] *prime[k] * prime[k] * prime[k];
                if (z >= n)break;
                if (x + y + z <= n)ans[cnt ++] = x + y + z;
            }
        }
    }
    sort(ans, ans + cnt);
    cnt = unique(ans, ans + cnt) - ans;
    return cnt;
}
int main()
{
    init();
    int n;
    cin >> n;
    cout << solve(n) << endl;
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值