参考资料

原题链接砍柴 - 蓝桥云课 (lanqiao.cn)

区间质数搜索——埃拉托斯特尼筛法和欧拉筛法-CSDN博客


思路

质数筛 + 二分 + 博弈 + 状态机(只因bushi)

$$

状态转移方程 dp[i] = !dp[i-p]

$$

由原始题意可以看出

砍树长度限制为小于其长度的质数——暗示你使用质数筛

交替砍柴——状态机

最优策略——寻找小于当前长度的使自己必胜的质数 p——二分搜索加快速度

状态机定义 dp[i] 表示长度为 i 时先手的胜负态

代码 1 ——优化埃氏筛

import java.util.*;
public class Main {
    static int t;
    static int []wood;
    static List<Integer> primes;
    // 求2~n的所有质数  优化埃氏筛法
    static void Sieve(int n){
        primes = new ArrayList<>();
        boolean []st = new boolean[n+1];
        //添加2~根号n的所有质数,并标记<=n的所有合数
        for(int i = 2;i*i<n;i++){
            if(!st[i]){
                primes.add(i);
                for(int j = i*i;j<=n;j+=i){//根据当前质因子筛去其倍数
                    st[j] = true;
                }
            }
        }
        //添加根号n到n的所有质数
        for(int i = (int)Math.sqrt(n)+1;i<=n;i++){
                if(!st[i]){
                    primes.add(i);
                }
            }
    }
    // 求小于n的最大质数
    static int maxPrimeLt(int n){
        int l = 0,r = primes.size()-1;
        while(l<r){
            int mid = l + r + 1>>1;
            if(primes.get(mid)>n){
                r = mid - 1;
            }
            else{
                l = mid;
            }
        }
        return l;
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        t = sc.nextInt();
        wood = new int[t];
        int maxLen = 0;
        //接收t根木头并求得最大长度
        for (int i = 0; i < t; i++) {
            int val = sc.nextInt();
            maxLen = Math.max(maxLen, val);
            wood[i] = val;
        }
        // 求2~maxLen的所有质数
        Sieve(maxLen);
        //状态数组
        boolean []dp = new boolean[maxLen+1];
        //状态转移方程 dp[i] = !dp[i-p]  p为小于i的最大质数  存在即可说明状态转移成功
        for(int i = 2;i<=maxLen;i++){//枚举所有可能砍去的长度
            for(int j = maxPrimeLt(i);j>=0;j--){//枚举状态转移的长度,即下一步的状态
                if(!dp[i-primes.get(j)]){
                    dp [i] = true;
                    break; //存在即可说明状态转移成功
                }
            }
        }
        StringBuilder res = new StringBuilder();
        for(int i = 0;i<t;i++){
            if(dp[wood[i]])
                res.append("1\n");
            else
                res.append("0\n");
        }
        System.out.println(res);
        sc.close();
    }
}

代码 2——欧拉筛

import java.util.*;
public class Main {
    static int t;
    static int []wood;
    static List<Integer> primes;
    // 求2~n的所有质数  优化埃氏筛法
    static void Sieve(int n){
        primes = new ArrayList<>();
        boolean []st = new boolean[n+1];
        for(int i = 2;i<=n;i++){
            if(!st[i]){
                primes.add(i);
            }
            for(Integer p:primes){
                if(i*p>n)
                    break;
                st[i*p] = true;
                if(i%p==0){
                    break;
                }
            }
        }
    }
    // 求小于n的最大质数
    static int maxPrimeLt(int n){
        int l = 0,r = primes.size()-1;
        while(l<r){
            int mid = l + r + 1>>1;
            if(primes.get(mid)>n){
                r = mid - 1;
            }
            else{
                l = mid;
            }
        }
        return l;
    }
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        t = sc.nextInt();
        wood = new int[t];
        int maxLen = 0;
        //接收t根木头并求得最大长度
        for (int i = 0; i < t; i++) {
            int val = sc.nextInt();
            maxLen = Math.max(maxLen, val);
            wood[i] = val;
        }
        // 求2~maxLen的所有质数
        Sieve(maxLen);
        //状态数组
        boolean []dp = new boolean[maxLen+1];
        //状态转移方程 dp[i] = !dp[i-p]  p为小于i的最大质数  存在即可说明状态转移成功
        for(int i = 2;i<=maxLen;i++){//枚举所有可能砍去的长度
            for(int j = maxPrimeLt(i);j>=0;j--){//枚举状态转移的长度,即下一步的状态
                if(!dp[i-primes.get(j)]){
                    dp [i] = true;
                    break; //存在即可说明状态转移成功
                }
            }
        }
        StringBuilder res = new StringBuilder();
        for(int i = 0;i<t;i++){
            if(dp[wood[i]])
                res.append("1\n");
            else
                res.append("0\n");
        }
        System.out.println(res);
        sc.close();
    }
}

第十五届蓝桥杯javaA组 砍柴 (两种写法)详解的更多相关文章

  1. 第九届蓝桥杯JavaA组省赛真题

    解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.分数 题目描述 1/1 + 1/2 + 1/4 + 1/8 + 1/16 + - 每项是前一项的一半,如果一共有20项, 求这个和是多 ...

  2. 第六届蓝桥杯JavaA组国(决)赛真题

    解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.胡同门牌号 小明家住在一条胡同里.胡同里的门牌号都是连续的正整数,由于历史原因,最小的号码并不是从1开始排的. 有一天小明突然发现了有 ...

  3. 第七届蓝桥杯JavaA组国(决)赛部分真题

    解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.阶乘位数 阶乘位数 9的阶乘等于:362880 它的二进制表示为:1011000100110000000 这个数字共有19位. 请你计 ...

  4. 第七届蓝桥杯JavaA组省赛真题

    解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.煤球数量 煤球数目 有一堆煤球,堆成三角棱锥形.具体: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形), 第 ...

  5. 第六届蓝桥杯JavaA组省赛真题

    解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.熊怪吃核桃 题目描述 森林里有一只熊怪,很爱吃核桃.不过它有个习惯,每次都把找到的核桃分成相等的两份,吃掉一份,留一份.如果不能等分, ...

  6. 第6届蓝桥杯javaA组第7题,牌型种数,一道简单的题带来的思考

    题目: 小明被劫持到X赌城,被迫与其他3人玩牌. 一副扑克牌(去掉大小王牌,共52张),均匀发给4个人,每个人13张. 这时,小明脑子里突然冒出一个问题: 如果不考虑花色,只考虑点数,也不考虑自己得到 ...

  7. 第十届蓝桥杯JavaB组省赛真题

    试题 A: 组队 本题总分:5 分 [问题描述] 作为篮球队教练,你需要从以下名单中选出 1 号位至 5 号位各一名球员, 组成球队的首发阵容. 每位球员担任 1 号位至 5 号位时的评分如下表所示. ...

  8. 2018年第九届蓝桥杯B组题C++汇总解析-fishers

    2018年第九届蓝桥杯B组题C++解析-fishers 题型 第一题:第几天 第二题:明码 第三题:乘积尾零 第四题:测试次数 第五题:快速排序 第六题:递增三元组 第七题:螺旋折线 第八题:日志统计 ...

  9. 《手把手教你》系列技巧篇(四十五)-java+ selenium自动化测试-web页面定位toast-上篇(详解教程)

    1.简介 在使用appium写app自动化的时候介绍toast的相关元素的定位,在Web UI测试过程中,也经常遇到一些toast,那么这个toast我们这边如何进行测试呢?今天宏哥就分两篇介绍一下. ...

  10. 第十届蓝桥杯JavaB组总结

    去年参加了第九届蓝桥杯C/C++B组,很捞,做了大概5道题,就好像就做对了2道结果填空题,编程题只做了一个(只通过了部分测试数据),最后拿了个省三,但是班上那些平时没有认真准备的都拿了省二 今年想好好 ...

随机推荐

  1. js脚本实现文本文件格式批量转换

    问题: 在Windows环境下,从某些软件中导出的文本格式的数据,选择了默认的ANSI格式.双击打开数据文件后,一切正常,没乱码问题.但是为什么自己的代码里,先按照ANSI格式打开,在转换为UTF8, ...

  2. IPv6的优势分析

    本文分享自天翼云开发者社区<IPv6的优势分析>,作者:没烦恼 IPv6的优势分析 1.更大的地址空间 IPv6中IP地址的长度为128位,其地址容量则达到了2^128个,远远大于IPv4 ...

  3. 传国玉玺易主,ai.com竟然跳转到国产AI

    一.震惊!输入ai.com网址竟然见证历史 今天我在地址栏随手敲了个ai.com,结果网页"唰"地一下--居然跳到了国产AI新贵DeepSeek的官网!这感觉就像在胡同口买煎饼,结 ...

  4. LangChain基础篇 (06)

    LangChain 核心模块 Agent(构建复杂应用的代理系统) ReAct: Reasoning + Acting ReAct Prompt 由 few-shot task-solving tra ...

  5. .NET中 泛型 + 依赖注入 的实现与应用

    在.NET中,注入泛型依赖项是一个常见的场景. 在依赖注入(DI)中使用泛型可以使得应用程序更加模块化.易于测试和扩展. 在ASP.NET Core中注册泛型服务 假设我们有一个需要注入的泛型接口 I ...

  6. 刚刚!百度搜索“换脑”引爆AI圈,正式接入DeepSeek R1满血版

    一.今天发现百度搜索出现已接入DeepSeek的提示,再也不用担心使用DeepSeek时出现"服务器繁忙,请稍后再试."的问题了.   在百度搜索首页出现[即刻体验AI搜索Deep ...

  7. OSAL架构

    OSAL操作系统最多可以支持16个任务,由任务功耗管理PwrMgr_task_state变量可知,而OSAL每个任务最多只能支持16个事件处理,理论上最大可以执行256个事件处理. 对于一些运算能力不 ...

  8. 【Matlab】基于KDtree的最近邻搜索和范围搜索

    摘要:介绍Matlab的rangesearch()函数和knnsearch()函数. rangesearch() -- 根据给定k-维数据集,返回指定距离范围内的所有数据点 knnsearch() - ...

  9. 【ABAQUS文档笔记】实体单元特性&剪切闭锁-沙漏问题-非协调模式-混杂单元

    来自ABAQUS DOCUMENT/GETTING STARTED WITH ABAQUS/CAE /USING CONTINUUM ELEMENTS 1. 单元公式和积分 1.1 full inte ...

  10. 记线上+线下培训思想i技巧感悟

    刚刚结束一场线下+线上培训 梳理一下,有几个问题: 1.虽然课件自己过了几遍,同时备注里写了一些提示 ,但是真正讲课的时候基本是没有过程特意去扫备注 注意备注应清晰,写核心关键字 2.分屏过程 需要在 ...