2023年算法精英大赛12月真题E题 等式 题型:枚举

75 阅读1分钟

赛氪OJ-专注于算法竞赛的在线评测系统 (saikr.com)

image.png 样例输入:

3

样例输出:

1

样例输入:

10

样例输出:

4

思想

1.枚举i,j,然后判断i*j是否是合数,不是合数就跳过当前数。

2.通过i,j去枚举k,判断k是否为素数,不是素数就跳过当前数。

3.如果i*j合法,k合法,cnt++;

4.输出cnt

code

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
int cnt;
const int N = 2e7 + 10;
bool book[N];

void prime() {
    book[0] = book[1] = true; // 0和1都不是质数
    for (int i = 2; i * i < N; i++) {
        if (!book[i]) { // 如果i是质数
            for (int j = i * i; j < N; j += i) { // 将i的倍数标记为非质数
                book[j] = true;
            }
        }
    }
}

signed main()
{
    cin >> n;
    prime(); // 调用筛法函数筛选质数
    for (int i = 1; i <= n; i++) {
        for (int j = 1; i*j <= n; j++) {
        
            if (!book[i * j])continue;  //i*j是素数就跳过
                int k = n - i * j;
                if (book[k])continue;   //k不是素数就跳过
                if (k >= 1 && k <= n && i * j + k == n) { // 确保k在合法范围内
                    
                         //cout << i << "*" << j << "+" << k << endl;
                        cnt++;
                }
        }
    }
    cout << cnt << endl;
    return 0;
}

image.png