试题 算法训练 Lift and Throw

问题描述

  给定一条标有整点(1, 2, 3, …)的射线. 定义两个点之间的距离为其下标之差的绝对值.

  Laharl, Etna, Flonne一开始在这条射线上不同的三个点, 他们希望其中某个人能够到达下标最大的点.

  每个角色只能进行下面的3种操作, 且每种操作不能每人不能进行超过一次.

  1.移动一定的距离

  2.把另一个角色高举过头

  3.将举在头上的角色扔出一段距离

  每个角色有一个movement range参数, 他们只能移动到没有人的位置, 并且起点和终点的距离不超过movement range.

  如果角色A和另一个角色B距离为1, 并且角色B没有被别的角色举起, 那么A就能举起B. 同时, B会移动到A的位置,B原来所占的位置变为没有人的位置. 被举起的角色不能进行任何操作, 举起别人的角色不能移动.同时, 每个角色还有一个throwing range参数, 即他能把举起的角色扔出的最远的距离. 注意, 一个角色只能被扔到没有别的角色占据的位置. 我们认为一个角色举起另一个同样举起一个角色的角色是允许的. 这种情况下会出现3个人在同一个位置的情况. 根据前面的描述, 这种情况下上面的两个角色不能进行任何操作, 而最下面的角色可以同时扔出上面的两个角色. 你的任务是计算这些角色能够到达的位置的最大下标, 即最大的数字x, 使得存在一个角色能够到达x.

输入格式

  输入共三行, 分别为Laharl, Etna, Floone的信息.

  每一行有且仅有3个整数, 描述对应角色的初始位置, movement range, throwing range.

  数据保证3个角色的初始位置两两不相同且所有的数字都在1到10之间.

输出格式

  仅有1个整数, 即Laharl, Etna, Flonne之一能到达的最大距离.

样例输入

9 3 3

4 3 1

2 3 3

样例输出

15

样例说明

  一开始Laharl在位置9, Etna在位置4, Flonne在位置2.

  首先, Laharl移动到6.

  然后Flonne移动到位置5并且举起Etna.

  Laharl举起Flonne将其扔到位置9.

  Flonne把Etna扔到位置12.

  Etna移动到位置15.

import java.util.Scanner;

public class Main {

    //地图的最大长度
public static final int MAXLEN = 50;
//坐标轴 标记当前位置是否有人
public static boolean[] Pos = new boolean[MAXLEN];
//标记当前操作是否执行过了
public static boolean visit[] = new boolean[9];
//最大能够到达的距离
public static int max;
//保持三人的状态数组
static Person[] p; public static void main(String[] args) {
Scanner s = new Scanner(System.in); p = new Person[3]; for (int i = 0; i < 3; i++) {
p[i] = new Person(s.nextInt(), s.nextInt(), s.nextInt(),
false, false, -1, false, false);
Pos[p[i].pos] = true;
} for (int i = 0; i < 9; i++) {
//第一次操作不能是扔别人 只能是举起或者移动
if ((i % 3) != 2) {
visit[i] = true;
dfs(i, 1);
visit[i] = false;
}
} System.out.println(max); } /**
* @return void
* @Author Tongsongqian
* @Description
* @Date 22:54 2020/2/3
* @Param [k 当前执行的操作 , step 当前执行的步数]
* k可以算出第 n 个人执行的操作,和对应的操作类型 m
* n=k/3
* m=k%3;
* m==0 表示移动
* m==1 表示举起
* m==2 表示扔出
**/ private static void dfs(int k, int step) {
int n = k / 3;
int m = k % 3; //移动
if (m == 0) {
//如果这个人已经移动过或者正在被举起或者正在举起别人 就不能移动
if (p[n].hasMoved || p[n].lifted || p[n].lifting) return; int i = 1;
//如果已经是最后一步 只需要移动最大距离
if (step == 9) {
i = p[n].maxMove;
} else {
//找出需要移动的人之前有没有别人 如果有人只需要从离他最近的人的前一个位置开始搜索
for (int j = 1; j < p[n].pos; j++) {
if (Pos[j]) {
int l = -(p[n].pos - j - 1);
i = i < l ? i : l;
//因为要找到离当前需要移动的人最近的人 因此这里不能break
}
}
//如果他之前的人的前一个位置不能超过他能移动到的最大距离
i = i > -p[n].maxMove ? i : -p[n].maxMove;
} for (; i <= p[n].maxMove; i++) {
//只有当移动的位置附近有人或者移动的距离是最大距离才有意义
if (Pos[p[n].pos + i - 1] || Pos[p[n].pos + i + 1] || i == p[n].maxMove) {
//不能移动到地图之外 移动到的位置不能有人
if ( p[n].pos+i>0 && !Pos[p[n].pos+i] )
//不能移动到原处
if (i==0) continue; //移动
Pos[p[n].pos]=false; //移动前的位置需要标记为没人
p[n].pos+=i; //向前走
p[n].hasMoved=true; //标记已经移动过
Pos[p[n].pos]=true; //移动到的位置需要标记为有人
max=max<p[n].pos?p[n].pos:max; //更新最大值 //继续搜索
for (int j = 0; j < 9; j++) {
//当前操作没有进行过才搜索
if (!visit[j]) {
visit[j]=true;
dfs(j,step+1);
visit[j]=false;
}
} //回溯
p[n].hasMoved=false;
Pos[p[n].pos]=false;
p[n].pos-=i;
Pos[p[n].pos] = true; } } }
//举起
else if (m == 1) {
//如果当前的人已经举起过别人 或者 已经被举起 或者正在举着别人 直接返回
if (p[n].hasLifted || p[n].lifted || p[n].lifting) return; //遍历三个人
for (int i = 0; i < 3; i++) {
//如果当前这个人的附近有人 才可以举起别人
if (Math.abs(p[i].pos - p[n].pos) == 1) {
//如果旁边的这个人已经被别人举起了则不能重复举起
if (p[i].lifted) continue; p[n].lifting=true; //标记当前这个人正在举着别人
p[n].lift=i; //标记当前这个人举着的是哪一个人
p[n].hasLifted=true; //标记这个人已经举过别人了 p[i].lifted=true; //标记被举着的人当前被举着
int temp=p[i].pos; //存储被举着的人被举之前的位置 用于回溯调用
Pos[p[i].pos]=false; //被举着的人直接占用的位置要清空
p[i].pos=p[n].pos; //被举着的人要移动到举人者的位置
//如果被举的人还举着别人 那么这个人也要相应地移动过来
if (p[i].lifting) {
int j=p[i].lift;
p[j].pos=p[i].pos;
} //继续搜索
for (int j = 0; j < 9; j++) {
if (!visit[j]) {
visit[j] = true;
dfs(j, step + 1);
visit[j] = false;
}
} //回溯
p[n].lifting=false;
p[n].lift=-1;
p[n].hasLifted=false; p[i].pos=temp;
Pos[p[i].pos]=true;
p[i].lifted=false;
if (p[i].lifting) {
int j = p[i].lift;
p[j].pos=p[i].pos;
}
}
}
}
//扔
else {
//如果当前的人没有举起人 或者正在被别人举起就返回
if (!p[n].lifting || p[n].lifted ) return; int i=1;
//如果当前已经是最后一步 只要让这个人向前扔出最大距离
if (step == 9) {
i = p[n].maxThrow;
} else {
//否则需要从距离他最近的前一个人的前一个位置开始搜索
for (int j = 1; j < p[n].pos; j++) {
if (Pos[j]) {
int l = -(p[n].pos - j - 1);
i=i<l?i:l;
}
}
//距离他最近的前一个人的前一个位置不能超过了扔的距离的最大值
i=i>-p[n].maxThrow?i:-p[n].maxThrow;
} for (; i <=p[n].maxThrow ; i++) {
//只有扔到的位置前后有人 或者扔出了最大距离才有意义
if (Pos[p[n].pos + i - 1] || Pos[p[n].pos + i + 1] || i == p[n].maxThrow) {
//扔出的距离不能超出地图 扔到的位置上也不能有人
if (p[n].pos + i > 0 && !Pos[p[n].pos + i]) {
//如果扔的距离是0 就进行下一次搜索
if (i==0) continue; p[n].lifting=false; //扔出去后当前这个人没有举起任何人
int j=p[n].lift;
p[j].pos+=i; //更新被扔人的位置
p[n].lift=-1; //当前这个人没有举起任何人
Pos[p[j].pos]=true; //被人人的新位置被标记为占用
p[j].lifted=false; //被扔的人被扔之后没有被任何人举起
max=max>p[j].pos?max:p[j].pos; //更新最大值 //如果被人人还举着别人 那么这个人的位置也要同步更新
if (p[j].lifting) {
int t = p[j].lift;
p[t].pos=p[j].pos;
} //继续搜索
for (int q = 0; q < 9; q++) {
if (!visit[q]) {
visit[q] = true;
dfs(q, step + 1);
visit[q] = false;
}
} //回溯 p[n].lifting=true;
p[n].lift=j; Pos[p[j].pos]=false;
p[j].pos-=i;
p[j].lifted=true;
if (p[j].lifting) {
int t=p[j].lift;
p[t].pos=p[j].pos;
}
}
}
}
} } } class Person { //当前位置
int pos;
//是否举着别人
boolean lifting;
//是否被举着
boolean lifted;
//正在举起的人
int lift;
//是否移动过了
boolean hasMoved;
//是否举起过了
boolean hasLifted;
//是否扔过不需要记录 因为只能举起别人一次
int maxThrow;
int maxMove; public Person(int pos, int maxMove, int maxThrow, boolean lifting, boolean lifted, int lift, boolean hasMoved, boolean hasLifted) {
this.pos = pos;
this.lifting = lifting;
this.lifted = lifted;
this.lift = lift;
this.hasMoved = hasMoved;
this.hasLifted = hasLifted;
this.maxThrow = maxThrow;
this.maxMove = maxMove;
}
}

Java实现 蓝桥杯 算法训练 Lift and Throw的更多相关文章

  1. Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)

    试题 算法训练 猴子吃包子 问题描述 从前,有一只吃包子很厉害的猴子,它可以吃无数个包子,但是,它吃不同的包子速度也不同:肉包每秒钟吃x个:韭菜包每秒钟吃y个:没有馅的包子每秒钟吃z个:现在有x1个肉 ...

  2. Java实现蓝桥杯 算法训练 大等于n的最小完全平方数

    试题 算法训练 大等于n的最小完全平方数 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 输出大等于n的最小的完全平方数. 若一个数能表示成某个自然数的平方的形式,则称这个数为完全平 ...

  3. java实现 蓝桥杯 算法训练 Password Suspects

    问题描述 在年轻的时候,我们故事中的英雄--国王 Copa--他的私人数据并不是完全安全地隐蔽.对他来说是,这不可接受的.因此,他发明了一种密码,好记又难以破解.后来,他才知道这种密码是一个长度为奇数 ...

  4. Java实现 蓝桥杯 算法训练VIP 报数(暴力+数学)约瑟夫环问题

    试题 算法训练 报数 问题描述 现有n个同学站成一圈,顺时针编号1至n.从1号同学开始顺时针1/2报数,报到1的同学留在原地,报到2的同学退出圆圈,直到只剩一名同学为止.问最后剩下的同学编号. 输入格 ...

  5. Java实现蓝桥杯 算法训练 ALGO-15 旅行家的预算

    问题描述 一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的).给定两个城市之间的距离D1.汽车油箱的容量C(以升为单位).每升汽油能行驶的距离D2.出发点每升汽油价格P和沿 ...

  6. Java实现 蓝桥杯 算法训练 审美课

    算法训练 审美课 时间限制:1.0s 内存限制:256.0MB 提交此题 问题描述 <审美的历程>课上有n位学生,帅老师展示了m幅画,其中有些是梵高的作品,另外的都出自五岁小朋友之手.老师 ...

  7. Java实现 蓝桥杯 算法训练 多阶乘计算

    试题 算法训练 多阶乘计算 问题描述 我们知道,阶乘n!表示n*(n-1)(n-2)-21, 类似的,可以定义多阶乘计算,例如:5!!=531,依次可以有n!..!(k个'!',可以简单表示为n(k) ...

  8. Java实现 蓝桥杯 算法训练 找零钱

    试题 算法训练 找零钱 问题描述 有n个人正在饭堂排队买海北鸡饭.每份海北鸡饭要25元.奇怪的是,每个人手里只有一张钞票(每张钞票的面值为25.50.100元),而且饭堂阿姨一开始没有任何零钱.请问饭 ...

  9. Java实现 蓝桥杯 算法训练 第五次作业:字符串排序

    试题 算法训练 第五次作业:字符串排序 问题描述 输入一个小写字符串,按从小到大的顺序输出. 输入格式 bcaed 输出格式 abcde 顶格输出,中间没有空格 样例输入 一个满足题目要求的输入范例. ...

随机推荐

  1. [hdu4911]逆序对相关

    思路:由于只能交换相邻的数,所以每次最多减小1个逆序对(且如果存在逆序对那么肯定可以减小1个)!于是乎..就是统计逆序对的裸题了.树状数组或归并都行. #pragma comment(linker, ...

  2. 手机app传统邀请码安装与免邀请码安装区别,如何选择呢?

    App 邀请机制是每个产品几乎必做的功能点,它一般以两种形式存在:一是作为常置功能用于推荐,二是作为裂变活动用于邀请. 无论以哪种形式出现,都可以归为社交分享的一种表现方式.相较于营销推广,邀请好友机 ...

  3. android 压缩图片大小,防止OOM

    android开发中,图片的处理是非常普遍的,经常是需要将用户选择的图片上传到服务器,但是现在手机的分辨率越来越好了,随便一张照片都是2M或以上,如果直接显示到ImageView中,是会出现OOM的, ...

  4. 【SMB源码解析系列】——001.JumpEngine函数

    在SMB的源码中大概有不到20处看起来很奇怪的指令,它的格式是通过jsr指令调用一个名为JumpEngine的函数,其后并不是跟随某些后续的逻辑指令,而是通过.dw定义了一系列16位地址. 我们可以看 ...

  5. 在linux下执行git clone、git pull 、git push等操作免密

    1. 通过ssh密钥实现 ssh-keygen -t rsa -C "你的邮箱" -f "自己定义的目录" 打开: id_rsa.pub ,将文件内容复制到 g ...

  6. 2020版Adobe全家桶介绍及免费下载安装

    前言 Adobe公司创建于1982年,是世界领先的数字媒体和在线营销解决方案供应商.公司总部位于美国加利福尼亚州圣何塞.Adobe 的 客户包括世界各地的企业.知识工作者.创意人士和设计者.OEM合作 ...

  7. 学习Echarts:(二)异步加载更新

    这部分比较简单,对图表的异步加载和更新,其实只是异步获取数据然后通过setOption传入数据和配置而已. $.get('data.json').done(function (data) { myCh ...

  8. RAID0、RAID1及RAID5的区别详解

    目前已有的RAID(Redundant Array of Independent Disks,独立冗余磁盘阵列)技术有很多种,但是RAID0.RAID1.RAID5是最常见的几种方案. 1 RAID0 ...

  9. npm run build 时 报 __webpack_public_path__ = window.webpackPublicPath; 中的windows未定义

    原本 webpack.js在webpack.config.babel.js同目录下,在app.jsx中引用,用mac打包没问题,但是window就报window未定义,改到src和app.jsx同目录 ...

  10. 一个导致JVM物理内存消耗大的Bug

    概述 最近我们公司在帮一个客户查一个JVM的问题(JDK1.8.0_191-b12),发现一个系统老是被OS Kill掉,是内存泄露导致的.在查的过程中,阴差阳错地发现了JVM另外的一个Bug.这个B ...