HDU 5037 题解
来源:互联网 发布:c语言开发环境 编辑:程序博客网 时间:2024/06/06 07:49
转载请注明出处,http://blog.csdn.net/Bule_Zst/article/details/77884387
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5037
Problem Description
Once upon a time, there is a little frog called Matt. One day, he came to a river.
The river could be considered as an axis.Matt is standing on the left bank now (at position 0). He wants to cross the river, reach the right bank (at position M). But Matt could only jump for at most L units, for example from 0 to L.
As the God of Nature, you must save this poor frog.There are N rocks lying in the river initially. The size of the rock is negligible. So it can be indicated by a point in the axis. Matt can jump to or from a rock as well as the bank.
You don’t want to make the things that easy. So you will put some new rocks into the river such that Matt could jump over the river in maximal steps.And you don’t care the number of rocks you add since you are the God.
Note that Matt is so clever that he always choose the optimal way after you put down all the rocks.
Input
The first line contains only one integer T, which indicates the number of test cases.
For each test case, the first line contains N, M, L (
And in the following N lines, each line contains one integer within (0, M) indicating the position of rock.
Output
For each test case, just output one line “Case #x: y”, where x is the case number (starting from 1) and y is the maximal number of steps Matt should jump.
Sample Input
21 10 552 10 336
Sample Output
Case #1: 2Case #2: 4
题目大意:
有一只萌萌哒小青蛙要过河,过河路线可以看成一个数轴,起点为0,终点为m。
小青蛙不会游泳,只能跳到数轴上一些有树桩的点直到跳过河,小青蛙一次能跳的最大距离是L。
小青蛙想用尽量少的步数过河,而你想让他跳尽量多的次数。
现在你可以向数轴上一些位置添加树桩,使青蛙顺利过河,并达到你的目的。青蛙是以最佳策略过河的。
— hdu5037 Frog — 贪心
方法:
首先将题目给的石头进行排序(坑点)(还需加上起始点与终点),之后遍历这些石头,维护变量last(上次跳跃的距离),基于x、y累加结果,具体逻辑流程看代码
算法核心讲解:
分了两种情况,last + x 大于等于 a + 1 与小于
首先明确一个结论,对于a、b、c三点,若b、c之间的距离为a+1,则一定可以让青蛙跳到c点的同时,让它这一步的步长等于a与b之间的距离(<= ability)。证明如下:
现已确定abc三点,且青蛙在b点无法跳跃到c点
那么,青蛙从b点起跳,下一个落脚点一定是d点(满足:d-a == ability+1),因为若存在d1落脚点(< d),则青蛙就可以直接从a点跳到d1而不经过b了。
接下来,从d起跳,下一个落脚点一定是e(满足:e-b == ability+1)
a、b、d、e、c
因为e-b == ability+1,所以c与e重合
a、b、d、e
d - a == e - b
所以e - d == b - a
证毕
现在来解释代码
首先计算出y,即两石头间(a、b)存在y个ability+1的距离,所以结果加上2*y,设跳完这y的距离之后的落脚点为k,那么根据之前的结论,跳到k的这一步的步长为最初跳到a点的步长(last)
此时,距离b点还剩下x的距离,如果x加上last小于等于ability,那么青蛙就肯定不会落脚k点,而是直接跳到b点,而如果大于ability,那么青蛙只能跳到k点再跳到b点,所以要再加一
代码:
// @Team : nupt2017team12// @Author : Zst#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <string>#include <vector>#include <cmath>#include <algorithm>#include <map>using namespace std;#define LL long long#define MOD 1000000007#define CLR(a,x) memset(a,x,sizeof(a))#define INF 0x3f3f3f3f#define pb push_back#define FOR(i,a,b) for( int i = ( a ); i <= ( b ); ++i )const int N = 2*1e5+7;int n, d, a;int stone[N];int main(){ // freopen( "F.txt", "r", stdin ); int w; scanf( "%d", &w ); int cases = 1; while( w-- ) { scanf( "%d%d%d", &n, &d, &a ); FOR( i, 1, n ) { scanf( "%d", stone+i ); } stone[++n] = d; stone[0] = 0; sort( stone, stone+n+1 ); int last = a; int ans = 0; FOR( i, 1, n ) { int x = ( stone[i] - stone[i-1] ) % ( a + 1 ); int y = ( stone[i] - stone[i-1] ) / ( a + 1 ); if( last + x >= a + 1 ) { ans += 2 * y + 1; last = x; } else { ans += 2 * y; last = last + x; } } printf( "Case #%d: %d\n",cases++,ans); } return 0;}
- HDU 5037 题解
- hdu 4602题解
- hdu 1789题解
- HDU 4665 题解
- HDU 4710题解
- HDU 4715题解
- hdu 1087题解
- hdu 2844题解
- hdu 2845 题解
- hdu 4007题解
- hdu 4004题解
- hdu 1879题解报告
- HDU 2180 时钟 题解
- HDU 1425 sort 题解
- HDU 1015 Safecracker 题解
- HDU Computer Transformation1041 题解
- HDU 题解 1024
- hdu 4451Dressing题解
- 阿达是法师打发手法
- JVM(1):Java 类的加载机制
- __FILE__,realpath和dirname,
- redis命令大全(二)
- 数据库三范式简单记
- HDU 5037 题解
- python读写txt——实现qq记录格式优化
- 入门赛5
- SpringMVC接收数组
- NetBeans配置Xdebug 远程调试PHP
- 从零开始学Scala(一)——Scala环境搭建与第一行代码
- Codeforces Round #433 (Div. 2, based on Olympiad of Metropolises) A,B,C
- bootstarp table 使用及常用参数说明
- Resharper快捷键与VS冲突