参考资料

原题链接砍柴 - 蓝桥云课 (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. ctfshow--web9 md5二进制格加密的绕过

    dirsearch 扫到robots文件 查看一下 发现有个index.phps文件 访问这个index.phps,可以下载下来 我们来审计一下这里的代码 <?php $flag="& ...

  2. python教程合集(更新中)

    python教程目录 基础 hello world 变量 输入输出

  3. el-table当前行的获取和设置,用于表格行操作

    1.在vue的data区声明当前行变量对象,如果当前行的信息用于了按钮的状态则需要赋予默认值,否则会报找不到属性的错误,比如下面会用到当前记录的status属性值控制按钮是否可用. //表格选中的行 ...

  4. 离散最大似然法与 OI

    若总体属于离散型,其分布律在参数 \(\theta\) 作用下 \(P\{X=x\}=p(x;\theta),\Theta=\{\theta\}\) 的形式已知,设 \(X_1,X_2,\dots,x ...

  5. 小程序开发实战案例五 | 小程序如何嵌入H5页面

    在接入小程序过程中会遇到需要将 H5 页面集成到小程序中情况,今天我们就来聊一聊怎么把 H5 页面塞到小程序中. 本篇文章将会从下面这几个方面来介绍: 小程序承载页面的前期准备 小程序如何承载 H5 ...

  6. yarn的安装与配置(秒懂yarn用法)

    安装和配置Yarn可以通过以下步骤完成: 安装Node.js:首先,确保已经安装了Node.js.可以通过在终端中运行node -v来检查是否已安装.如果没有安装,可以从Node.js官方网站(htt ...

  7. 全程使用 AI 从 0 到 1 写了个小工具

    背景 好长时间没写技术方面的文章了,主要的原因是AI的发展实在太快太快,尤其是从去年ChatGPT的普及到今年DeepSeek的爆火,AI的世界可谓是三天一个小变化五天一个大版本,AI的能力每天都在以 ...

  8. 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能

    葡萄城 AI 搜索接入 DeepSeek 在软件开发的广阔领域中,信息获取的效率直接影响开发进程的快慢.葡萄城始终致力于为开发者打造高效.智能的开发环境.自去年12月上线以来,AI 搜索功能已在帮助开 ...

  9. 【ABAQUS 二次开发笔记】读入TXT分析结果&输出csv文件

    abaqus分析之后,很多结果可以输出dat,msg,sta等文件中.可以用记事本.notpad++.editplus等软件打开编辑. 但是往往无法直接用excel.origin等软件打开,比如对结构 ...

  10. python 二级 第三方库(pip 、pyinstaller、jieba、wordcloud)

    安装方式 首选pip安装,pip安装失败选择自定义安装.文件安装,一般windows系统pip安装有时会失败 pip安装 pip -h 查看指令 自定义安装 路径: https://www.scipy ...