蓝桥杯2024年第十五届省赛真题-砍柴

题目 3224: 蓝桥杯2024年第十五届省赛真题-砍柴

时间限制: 3s 内存限制: 512MB

题目描述

小蓝和小乔正在森林里砍柴,它们有 T 根长度分别为 n1, n2, · · · , nT 的木头。对于每个初始长度为 n 的木头,小蓝和小乔准备进行交替砍柴,小蓝先出手。每次砍柴时,若当前木头长度为 x ,需要砍下一截长度为 p 的木头,然后换另一个人继续砍,其中 2 ≤ p ≤ x 且 p 必须为质数。当轮到某一方时 x = 1 或x = 0 ,它就没法继续砍柴,它就输了。它们会使用最优策略进行砍柴。请对每根木头判断是小蓝赢还是小乔赢,如果小蓝赢请输出 1 (数字 1),如果小乔赢请输出 0 (数字 0)。

输入格式

输入的第一行包含一个正整数 T,接下来 T 行,每行包含一个正整数,其中第 i 的整数为 ni 。

输出格式

输出 T 行,每行包含一个整数,依次表示对于每一根木头的答案。

样例输入复制

3

1

2

6

样例输出复制

0

1

1

提示

【样例说明】

对于 n1 = 1 ,由于当前长度 x = 1 ,小蓝直接输掉,小乔赢;

对于 n2 = 2 ,小蓝选择 p = 2 ,轮到小乔时当前长度 x = 2 − 2 = 0 ,小乔输掉,小蓝赢;

对于 n3 = 6 ,小蓝选择 p = 5 ,轮到小乔时 x = 6 − 5 = 1 ,小乔输掉,小蓝赢。

【评测用例规模与约定】

对于 20% 的评测用例,1 ≤ ni ≤ 103;对于所有评测用例,1 ≤ ni ≤ 105 ,1 ≤ T ≤ 104

1.分析

1.我们知道0和1的长度是必输的长度,那么只要减去一个质数等于必输的长度,那么就必赢。

2.反过来,我们减去一个必输的长度,如果得到的是一个质数,那么是必赢的。

为什么要反过来呢,因为必输的长度比质数的数量要少,枚举的次数会变少,个人认为。

2.代码

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
typedef long long LL;
const int MAX = 1e5 + 100;
int h[MAX], n;    //记录结果的数组
int a[MAX], num;  //存储必输的树木长度
int idx[MAX];     //标记数组,0  1 和非素数标记为1
int re[MAX], r;   //存储素数
int t[MAX];       //存储询问

void init(int x) {
    idx[0] = 1;               //标记初始化,因为0和1不是素数
    idx[1] = 1;
    for (int i = 2; i <= x; i++) {
        if (!idx[i]) {     //是素数
            re[r++] = i;   //记录
            h[i] = 1;      //长度为素数,必赢
        }
        else {
            a[num++] = i;          //判断长度是否会输,先记录,如果不是再移除
            for (int j = 0; j < num-1; j++) {  //遍历必输的长度
                if (!idx[i - a[j]]) {       //如果减去必输的长度等于素数,这个长度必赢
                    h[i] = 1, num--;
                    break;
                }
            }
        }
        for (int j = 0; re[j] <= x / i; j++) {   //筛素数
            idx[re[j] * i] = 1;
            if (i % re[j] == 0) break;
        }

    }
}

int main() {
    cin >> n;
    a[num++] = 0;         //初始化两个必输的长度
    a[num++] = 1;
    int x=0;
    for (int i = 0; i < n;i++) {   //输入

        cin >> t[i];
        x =max(x, t[i]);           //记录最大值,不然会超时
    }
    init(x); 
    for (int i = 0; i < n; i++) {    //输出
        cout << h[t[i]] << endl;
    }
    return 0;
}
相关推荐
YuforiaCode1 小时前
第十四届蓝桥杯 2023 C/C++组 飞机降落
c语言·c++·蓝桥杯
YuforiaCode3 小时前
第十四届蓝桥杯 2023 C/C++组 平方差
c语言·c++·蓝桥杯
慕容青峰3 小时前
【蓝桥杯 2025 省 A 扫地机器人】题解
c++·算法·蓝桥杯·sublime text
骑驴看星星a5 小时前
P10416 [蓝桥杯 2023 国 A] XYZ
算法·职场和发展·蓝桥杯
不会计算机的捞地8 小时前
【数据结构入门训练DAY-14】 蓝桥杯2024年第十五届省赛真题-R 格式
数据结构·蓝桥杯
爱是小小的癌17 小时前
[第十六届蓝桥杯 JavaB 组] 真题 + 经验分享
经验分享·算法·蓝桥杯
ChoSeitaku19 小时前
NO.97十六届蓝桥杯备战|数论板块-最大公约数和最小公倍数|欧几里得算法|秦九韶算法|小红的gcd(C++)
c++·算法·蓝桥杯
谦川21 小时前
蓝桥杯 蜗牛 动态规划
职场和发展·蓝桥杯·动态规划
一只鱼^_1 天前
第 28 场 蓝桥月赛
开发语言·数据结构·c++·算法·面试·蓝桥杯
谦川1 天前
蓝桥杯 二进制问题 刷题笔记
笔记·职场和发展·蓝桥杯