题目

高僧斗法

古时丧葬活动中经常请高僧做法事。仪式结束后,有时会有“高僧斗法”的趣味节目,以舒缓压抑的气氛。

节目大略步骤为:先用粮食(一般是稻米)在地上“画”出若干级台阶(表示N级浮屠)。又有若干小和尚随机地“站”在某个台阶上。最高一级台阶必须站人,其它任意。(如图1所示)

两位参加游戏的法师分别指挥某个小和尚向上走任意多级的台阶,但会被站在高级台阶上的小和尚阻挡,不能越过。两个小和尚也不能站在同一台阶,也不能向低级台阶移动。

两法师轮流发出指令,最后所有小和尚必然会都挤在高段台阶,再也不能向上移动。轮到哪个法师指挥时无法继续移动,则游戏结束,该法师认输。

对于已知的台阶数和小和尚的分布位置,请你计算先发指令的法师该如何决策才能保证胜出。

输入数据为一行用空格分开的N个整数,表示小和尚的位置。台阶序号从1算起,所以最后一个小和尚的位置即是台阶的总数。(N<100,
台阶总数<1000)

输出为一行用空格分开的两个整数: A B, 表示把A位置的小和尚移动到B位置。若有多个解,输出A值较小的解,若无解则输出-1。

例如:

用户输入:

1 5 9

则程序输出:

1 4

再如:

用户输入:

1 5 8 10

则程序输出:

1 3

资源约定:

峰值内存消耗 < 64M

CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

普通博弈解法

对于一个特定局面,假设小和尚站的位置为 1 5 8 10,对于每个小和尚,尝试他当前能走的每一种步数,递归地判断新局面是否为,如果为可立即返回,如果当前局面每个小和尚都尝试了每种走法仍得不出的结果,那个对于当前法师,问题无解。

package org.lanqiao.algo.lanqiaobei.game;import java.util.Scanner;public class 高僧斗法 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);String[] ss = scanner.nextLine().split(" ");int[] x = new int[ss.length];//将小和尚的位置作为数组元素的值for (int i = 0; i < x.length; i++)x[i] = Integer.parseInt(ss[i]);if (!f(x)) {System.out.println(-1);} else {System.out.println(a + " " + b);}}static int a;static int b;private static boolean f(int[] x) {for (int i = 0; i < x.length - 1; i++) {//i位置向后尝试每一个可走的位置for (int j = x[i] + 1; j < x[i + 1]; j++) {int old = x[i];//记录i位置的原始值x[i] = j; //该表i位置的值try {//生成新的局面,如果这个局面判定对方输,那我们就赢了if (!f(x)) {a = old;b = j;return true;}} finally {x[i] = old;// 恢复i位置的值,进行下一次尝试}}}//for循环无法进行,或者整个for循环走完都没有一次变动能造成对方输,就返回falsereturn false;}
}

这种解法能应对1 5 8 10这样的输入,即个数少,间隔也小的,如果输入为1 30 40 99,在规定时间内是无法完成计算的。

尼姆堆解法

关于尼姆游戏,请移步如何在取硬币游戏中必胜?(有关尼姆博弈) - 知乎先了解下定义。

高僧斗法问题,怎么转换成类似取硬币这样的尼姆定式呢?
我们可以把两个小和尚作为一个组合生成一堆(间隔为堆数量),对于输入1 5 8 10,转换为尼姆堆N={3,1}。如果是奇数个小和尚,如1 5 8 10 13,我们在最高阶假想一个小和尚,这样第三堆数目为0,此时尼姆堆N={3,1,0}。

对于这样的尼姆堆,我方作为先手,堆元素全部异或起来结果为0,那我们处于先手必败局面,如果全部异或起来不为0,那我们可以改变尼姆堆某一堆的大小来促成异或值为0,这样把必败局面留给对方。

这样做效率能大大提升,因为只需要计算初始形态,不用考虑后面怎么走,因为一旦形成P-position,对方无论怎么走我都可以恢复为P-position

这里有一个比较难想通的问题是,为什么两两组合呢,组合之间的间隔不考虑吗?

如果我方走5号小和尚,无论怎么走对方都可以跟随,这样我们既定的尼姆堆没有任何的改变,也就是你造成了一个P-position对手又回你一个P-position。如果我们通过2、8号和尚改变了尼姆堆,形成全异或为0 的P-position局面,此时无论对手走什么我们可以跟随或改变另外一个尼姆堆来再给对方一个P-position

好了,上代码吧;比较烧脑:

static boolean f1(int[] x) {int[] N = new int[x.length / 2];// 堆的大小for (int i = 0; i < N.length; i++) {N[i] = x[2 * i + 1] - x[2 * i]-1;// 计算每个堆的数字}int k = N[0];for (int i = 1; i < N.length; i++) {k ^= N[i]; //连续做异或}// 现在异或不为0if (k != 0) {// 找到ni,其x位(k最高位)为1String kBinary = Integer.toBinaryString(k);for (int i = 0; i < N.length; i++) {//当前堆数字的二进制字符串String NiBinary = Integer.toBinaryString(N[i]);try {//右对齐后和k最高位在同一列的二进制为1if (NiBinary.charAt(NiBinary.length() - kBinary.length()) == '1') {a = x[2*i];  // 首动位置找到了//现在Ni 变为Ni' 使得尼姆堆的全体数字异或为0 只需把k所有为1的位对应的Ni上的位做0~1变换int Nii = N[i];for (int j = 0; j < kBinary.length(); j++) {if (kBinary.charAt(j)=='1')Nii^=(1<<(kBinary.length()-j-1));}// N[i]变为Nii肯定是缩小了,缩小的数就是a应该前进的数b = a+N[i]-Nii;break;}} catch (Exception e) {// 位数不够}}return true;}return false;}

改进之后即便输入1 30 40 99,也能很快计算出答案。

蓝桥杯题解-高僧斗法相关推荐

  1. 第十届蓝桥杯题解(部分)

    第十届蓝桥杯题解 注释:这段时间正好在写蓝桥杯的题,将部分的题目的解法和大家分享,代码中的网址是该代码蒟蒻当时参考其他大佬的题解文章所在的网址,鸣谢大佬,如有错误,欢迎各位大佬指正 有部分网址是提交答 ...

  2. 蓝桥历届试题 高僧斗法

    蓝桥历届试题 高僧斗法 高僧斗法 题目 思路 代码 高僧斗法 题目 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 古时丧葬活动中经常请高僧做法事.仪式结束后,有时会有"高 ...

  3. 2018蓝桥杯 题解

    一. 标题:分数 1/1 + 1/2 + 1/4 + 1/8 + 1/16 + .... 每项是前一项的一半,如果一共有20项, 求这个和是多少,结果用分数表示出来. 类似: 3/2 当然,这只是加了 ...

  4. ALGO-973 唯一的啥子( 蓝桥杯题解)

    啥子==傻子 兄弟们注意这个条件啊!!! 前100%数据保证n<=10^6,1<=k<min(当时圈中人数,1000) 因为循环n-1次,所以最后一次还没输入之前已经pass掉n-2 ...

  5. 【蓝桥杯题解】矩阵翻硬币

    历届试题 矩阵翻硬币 时间限制:1.0s 内存限制:256.0MB 提交此题 问题描述 小明先把硬币摆成了一个 n 行 m 列的矩阵. 随后,小明对每一个硬币分别进行一次 Q 操作. 对第x行第y列的 ...

  6. 蓝桥杯【介绍】和【如何准备才可以拿奖】

    本篇文章会简单的介绍一下蓝桥杯是啥?以及如何准备,文章中也会推荐一些好的关于蓝桥杯的博客. 以及刷题的OJ 目录 介绍蓝桥杯 准备 注意事项 最后 介绍蓝桥杯 蓝桥杯又被称为暴力杯.O钱杯. 蓝桥杯的 ...

  7. 2021年蓝桥杯第十二届软件赛省赛 C/C++ 大学B组 第二场 A-I

    目录 A: 求余 (水题) B:双阶乘(模拟) C:格点(模拟/枚举) D:整数分解 (闫式dp/数学) E:城邦(并查集+Kruskal) F:特殊年份(模拟) G:小平方 (模拟) H:完全平方数 ...

  8. 蓝桥杯算法训练-逗志芃的危机

    每日更新蓝桥杯题解, 有兴趣关注一波呀 文章目录 题目描述 题解 java代码 C++代码 题目描述 逗志芃又一次面临了危机.逗志芃的妹子是个聪明绝顶的人,相比之下逗志芃就很菜了.现在她妹子要和他玩一 ...

  9. 【蓝桥杯Web】2022年第十三届蓝桥杯Web大学组国赛真题解析

    前言 省赛真题解析见: 2022年第十三届蓝桥杯Web大学组省赛真题解析(完整版) 2022年第十三届蓝桥杯Web大学组省赛真题解析(精华版) 更多蓝桥杯题解请查阅专栏:蓝桥杯 之前写省赛解析时篇幅过 ...

最新文章

  1. tensorflow2:tf.app.run()
  2. Nginx 出現 500 Error 修復 (too many open file, connection)
  3. web touch 事件
  4. 正点原子stm32f429 pcb_正点原子【STM32-F407探索者】第十六章 电容触摸按键实验
  5. 笔记-中项案例题-2018年上-人力资源管理
  6. Elasticsearch Curator使用
  7. win7 蓝屏信息获取和处理
  8. 蔚来汽车再次自燃 股价继续大跌 官方:着火原因未明 已经启动调查
  9. mysql errorcode 1366_MySQL 字符集的问题引起的Error 1366错误 | Soo Smart!
  10. java properties null_正确使用Java Properties - Java综合 - Java - JavaEye...
  11. 组合数字c语言do while,C语言初学do while语句(对输入数字字符,特殊符号等,进行统计).docx...
  12. cpc专利电子申请客户端安装教程以及常见错误
  13. Python系列 之 ReportLab库 pdfgen模块Canvas对象绘制图形和文本
  14. windows最好用的mp3格式转换软件推荐
  15. gamit数据处理—5.遇到的问题
  16. 2023厦门大学计算机考研信息汇总
  17. emi滤波matlab,【原创】EMI 滤波器设计从入门到精通(三)
  18. uos应用_终极指标(UOS)应用法则
  19. MySQL 索引学习笔记
  20. layui操作完成后刷新页面

热门文章

  1. Java实现转账业务
  2. threejs 草场足球运动视角(三)
  3. excel中文本格式如何批量转化成数字
  4. Qt 用样式实现实心圆和空心圆
  5. ncurses库移植到arm平台
  6. 手游SDK-登录界面
  7. 第十一届蓝桥杯——解码
  8. 软考——软件测评师基础知识
  9. KDB集群搭建---(kas+krac)
  10. python程序设计论文_【程序设计论文】程序设计论文范文(共40篇)