挑战程序竞赛系列(22):3.2弹性碰撞
来源:互联网 发布:视频会议软件采购 编辑:程序博客网 时间:2024/06/16 12:53
挑战程序竞赛系列(22):3.2弹性碰撞
详细代码可以fork下Github上leetcode项目,不定期更新。
练习题如下:
- POJ 3684: Physical Experiment
- POJ 2674: Linear World
- POJ 1852: Ants
POJ 3684: Physical Experiment
有点考想象力,物理竞赛题,呵呵。思路:
两个球发生碰撞,可以看成擦肩而过(不损失任何能量),接着计算指定高度到地面所需要花费的时间,求得返回次数,如果返回次数为偶数,说明小球处于下落态,用下落公式求解即可。如果奇数呢?说明小球上升态,可以看成下落态用同一公式求解,真是会玩。
公式:
上升的公式可以自己推一推,不难。
代码如下:
void solve() { int n = ni(); while (n-- > 0){ int N = ni(); int H = ni(); int R = ni(); int T = ni(); double[] ans = new double[N]; for (int i = 0; i < N; ++i){ ans[i] = calc(T - i, H); } Arrays.sort(ans); for (int i = 0; i < N; ++i){ out.printf("%.2f%c",ans[i] + 2 * R * i / 100.0, (i + 1 == N ? '\n' : ' ')); } } } double calc(int T, int H){ if (T < 0) return H; double t = Math.sqrt(2.0 * H / 10.0); int k = (int) (T * 1.0 / t); if (k % 2 == 0){ double d = k * t; return H - 0.5 * 10.0 * (T - d) * (T - d); } else{ double d = k * t + t; return H - 0.5 * 10.0 * (T - d) * (T - d); } }
POJ 2674: Linear World
问想象力有多重要!直接给思路:
首先想象整个世界只有一只蚂蚁,于是可以计算出爬行时间最长的那一只,把它记下来。接着考虑其他蚂蚁,碰头时想象为两只蚂蚁交换姓名,擦肩而过即可。那么问题就剩下,统计这只蚂蚁跟多少只蚂蚁交换了姓名,最后交换的那一只就是答案了。那么到底跟谁交换了姓名呢?由于蚂蚁速度都一样,于是在前进路线上只会与那些逆行的蚂蚁碰头。统计出来后问题就解决了,需要注意答案的格式是截断小数不是四舍五入。
参考:http://www.hankcs.com/program/algorithm/poj-2674-linear-world.html
起初我在纠结算出那只走过最长距离的蚂蚁名字后,该怎么进行交换,结果呵呵哒了,统计和它反向的次数,并在原来基础上相加。
比如:
p n n p p n 0 1 2 3 4 5index = 0
可以得出一个结论,相邻两只反向蚂蚁,一定会碰撞,所以45位置的蚂蚁会反向一次,所以可以看成如下:
p n n p n p
一旦发生了碰撞,4位置的蚂蚁的方向发生了变化,名字还是4,既然如此,还可以继续传递:
p n n n p p
在这里可以发现一个规律,所有的n排在了p的右侧,而p全部跑到了右侧。
其实可以想象:
a. 任何相邻的两个小球发生碰撞,它们的次序不会发生变化(空间位置),因为碰撞后朝反方向走,真实情景中,它们的次序可以看作没有变化。
所以,对于任意球的碰撞,我们传递的无非是它们的撞击方向,碰撞一次,n变p,p变n,所以有了上面的尝试,而神奇的是:
经过长时间的碰撞后,会趋于一种稳定态,即 n n n p p这种事件,现在与第一个p发生最后一次碰撞的位置就显而易见了。
代码如下:
static class Inhabitant{ char direction; String name; double pos; } public static void main(String[] args) { Scanner in = new Scanner(System.in); while (true){ String line = in.nextLine().trim(); int n = Integer.parseInt(line); if (n == 0) break; line = in.nextLine(); String[] nums = line.trim().split(" +"); double l = Double.parseDouble(nums[0]); double v = Double.parseDouble(nums[1]); Inhabitant[] ants = new Inhabitant[n]; for (int i = 0; i < n; ++i){ ants[i] = new Inhabitant(); line = in.nextLine(); nums = line.trim().split(" +"); ants[i].direction = Character.toLowerCase(nums[0].charAt(0)); ants[i].name = nums[2]; ants[i].pos = Double.parseDouble(nums[1]); } Arrays.sort(ants, new Comparator<Inhabitant>() { @Override public int compare(Inhabitant o1, Inhabitant o2) { double pos1 = o1.pos; double pos2 = o2.pos; return pos1 < pos2 ? -1 : 1; } }); double maxDistance = 0.0; int index = 0; boolean forward = true; for (int i = 0; i < n; ++i){ if(ants[i].direction == 'n'){ if(ants[i].pos > maxDistance){ maxDistance = ants[i].pos; index = i; forward = false; } } else{ if ((l - ants[i].pos) > maxDistance){ maxDistance = l - ants[i].pos; index = i; forward = true; } } } if(forward){ int cnt = 0; for (int i = index; i < n; ++i){ if (ants[i].direction == 'n') cnt++; } index += cnt; } else{ int cnt = 0; for (int i = index; i >= 0; --i){ if(ants[i].direction == 'p') cnt++; } index -= cnt; } double result = maxDistance / v; System.out.printf("%13.2f %s\n",(int) (result * 100) / 100.0, ants[index].name); } in.close(); }
POJ 1852: Ants
轻松一下,注意下是所有蚂蚁落杆的最少时间。
代码如下:
void solve() { int c = ni(); while (c --> 0){ int l = ni(); int n = ni(); int[] ants = na(n); int min = 0, max = 0; for (int i = 0; i < n; ++i){ min = Math.max(min, Math.min(ants[i], l - ants[i])); max = Math.max(max, Math.max(ants[i], l - ants[i])); } out.println(min + " " + max); } }
- 挑战程序竞赛系列(22):3.2弹性碰撞
- 《挑战程序设计竞赛》3.2.3 常用技巧-弹性碰撞 POJ3684 2674
- 挑战程序竞赛系列(20):3.2尺取法
- 挑战程序竞赛系列(21):3.2反转
- 挑战程序竞赛系列(23):3.2折半枚举
- 挑战程序竞赛系列(34):3.2坐标离散化
- 挑战程序竞赛系列(81):4.3 LCA(1)
- 挑战程序竞赛系列(82):4.3 LCA(2)
- 挑战程序竞赛系列(1):2.3动态规划
- 挑战程序竞赛系列(4):2.1深度优先搜索
- 挑战程序竞赛系列(5):2.1广度优先搜索
- 挑战程序竞赛系列(6):2.1穷尽搜索
- 挑战程序竞赛系列(9):2.4优先队列
- 挑战程序竞赛系列(10):2.4并查集
- 挑战程序竞赛系列(11):2.5最短路径
- 挑战程序竞赛系列(12):2.5最小生成树
- 挑战程序竞赛系列(13):2.6辗转相除法
- 挑战程序竞赛系列(14):2.6素数
- win10系统搭建tensorflow1.2-GPU遇到的两个问题及解决方法。
- 小练习1
- STL之空间配置器源码(框架)剖析
- 守护进程
- AttributeError: module object has no attribute “Series”. Code works in Python
- 挑战程序竞赛系列(22):3.2弹性碰撞
- 看完忠爱无言电影的观后感
- python 3 下的scrapy安装问题,及运行中的问题
- struts2升级
- 2017.6.28 学习记录 Mysql的基础运用及代码
- 浅谈vue+webpack项目调试方法
- 使用Gitolite搭建轻量级的Git服务器
- Mac pro
- 深入理解bootstrap(转载)原文:http://blog.csdn.net/i10630226