文章目录

  • T1:Star Way To Heaven
    • 题目
    • 题解
    • 代码实现
  • T2:飞扬的小鸟
    • 题目
    • 题解
    • 代码实现

T1:Star Way To Heaven

题目

小 w 伤心的走上了 Star way to heaven。
到天堂的道路是一个笛卡尔坐标系上一个 n*m 的长方形通道 顶点在 (0,0) 和 (n,m) 。
小 w 从最左边任意一点进入,从右边任意一点走到天堂,最左最右的距离为 n,上下边界距离为m 。
其中长方形有 k 个Star ,每个 Star 都有一个整点坐标,Star 的大小可以忽略不计。
每个 Star 以及长方形上下两个边缘宇宙的边界都有引力,所以为了成功到达 heaven 小 w 离他们越远越好。
请问小 w 走到终点的路径上,距离所有星星以及边界的最小距离最大值可以为多少?

输入格式
一行三个整数n,m,k。
接下来 k 行,每行两个整数 表示一个点的坐标。
输出格式
一行一个数表示答案。保留到小数点后9位。

样例
样例输入
10 5 2
1 1
2 3
样例输出
1.118033989
数据范围与提示
对于 100% 的数据:k ≤ 6000;n,m ≤106

题解

以考虑二分答案result,对k个star都建一个半径为r的圆入手,
那么对于两个相交的圆把它们弄到一个集合,
对上下边界特殊判断,如果说上下边界被弄到了一个集合,
即说明,有若干个圆将矩形拦腰折断,分成了两个不连通的部分,是无法走到天堂的
则这个答案不合法,舍去

难道真的去搞二分??
把几个圆弄到一个集合就会想到并查集,再到kruskal,最后联想到得到prim算法,
现将一个边界加入集合,找到距离它最小的点,加入集合,
将与之相连的点的距离更新

如此加边,知道另一边界也加入集合中,此时刚好上下界拦腰截断,其实这时的maxdis为恰好不能走过去时的最小dis,那么只要小一点点,就符合了,精度不用怕

代码实现

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define MAXN 6005
#define LL long long
#define INF 10000000
int n, m, k;
double result;
double x[MAXN], y[MAXN], dis[MAXN];
bool vis[MAXN];double count ( int u, int v ) {return sqrt ( ( x[u] - x[v] ) * ( x[u] - x[v] ) + ( y[u] - y[v] ) * ( y[u] - y[v] ) );
}int main() {scanf ( "%d %d %d", &n, &m, &k );for ( int i = 1;i <= k;i ++ )scanf ( "%lf %lf", &x[i], &y[i] );for ( int i = 1;i <= k;i ++ )dis[i] = y[i];dis[k + 1] = m;for ( int i = 1;i <= k + 1;i ++ ) {int t = -1;double now = INF;for ( int j = 1;j <= k + 1;j ++ ) {if ( ! vis[j] && dis[j] < now ) {now = dis[j];t = j;}}result = max ( dis[t], result );if ( t == k + 1 ) return ! printf ( "%.9f", result * 0.5 );vis[t] = 1;for ( int j = 1;j <= k;j ++ ) {double tmp = count ( j, t );if ( ! vis[j] )dis[j] = min ( dis[j], max ( dis[t], tmp ) );}dis[k + 1] = min ( dis[k + 1], m - y[t] );}return 0;
}

T2:飞扬的小鸟

题目

Flappy Bird是一款风靡一时的休闲手机游戏。玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙。如果小鸟一不小心撞到了水管或者掉在地上的话,便宣告失败。

为了简化问题,我们对游戏规则进行了简化和改编:
游戏界面是一个长为 n,高为 m 的二维平面,其中有 k 个管道(忽略管道的宽度)。
小鸟始终在游戏界面内移动。小鸟从游戏界面最左边任意整数高度位置出发,到达游戏界面最右边时,游戏完成。

小鸟每个单位时间沿横坐标方向右移的距离为 1,竖直移动的距离由玩家控制。如果点击屏幕,小鸟就会上升一定高度 X,每个单位时间可以点击多次,效果叠加;如果不点击屏幕,小鸟就会下降一定高度 Y。小鸟位于横坐标方向不同位置时,上升的高度 XX 和下降的高度 Y 可能互不相同。
小鸟高度等于 0 或者小鸟碰到管道时,游戏失败。小鸟高度为 m 时,无法再上升。

现在,请你判断是否可以完成游戏。如果可以,输出最少点击屏幕数;否则,输出小鸟最多可以通过多少个管道缝隙。

输入格式
第 1 行有 3 个整数 n, m, k分别表示游戏界面的长度,高度和水管的数量,每两个整数之间用一个空格隔开;
接下来的 n 行,每行 22 个用一个空格隔开的整数 X 和 Y,依次表示在横坐标位置 0∼n−1 上玩家点击屏幕后,小鸟在下一位置上升的高度 X,以及在这个位置上玩家不点击屏幕时,小鸟在下一位置下降的高度 Y。
接下来 k 行,每行 33 个整数 P, L, H,每两个整数之间用一个空格隔开。每行表示一个管道,其中 P 表示管道的横坐标,L 表示此管道缝隙的下边沿高度,H 表示管道缝隙上边沿的高度(输入数据保证 P 各不相同,但不保证按照大小顺序给出)。

输出格式
共两行。
第一行,包含一个整数,如果可以成功完成游戏,则输出 1,否则输出 0。
第二行,包含一个整数,如果第一行为 1,则输出成功完成游戏需要最少点击屏幕数,否则,输出小鸟最多可以通过多少个管道缝隙。

输入输出样例
输入
10 10 6
3 9
9 9
1 2
1 3
1 2
1 1
2 1
2 1
1 6
2 2
1 2 7
5 1 5
6 3 5
7 5 8
8 7 9
9 1 3
输出
1
6

输入
10 10 4
1 2
3 1
2 2
1 8
1 8
3 2
2 1
2 1
2 2
1 2
1 0 2
6 7 9
9 1 4
3 8 10
输出
0
3
说明/提示
【输入输出样例说明】
如下图所示,蓝色直线表示小鸟的飞行轨迹,红色直线表示管道。

【数据范围】
对于 30%的数据:5≤n≤10,5≤m≤10,k=0,保证存在一组最优解使得同一单位时间最多点击屏幕 3次;
对于 50%的数据:5≤n≤20,5≤m≤10,保证存在一组最优解使得同一单位时间最多点击屏幕 3 次;
对于 70%的数据:5≤n≤1000,5≤m≤100;
对于 100%的数据:5≤n≤10000, 5≤m≤1000,0≤k<n, 0 < X < m, 0 < Y < m, 0 < P < n, 0≤L<H≤m, L + 1 < H

题解

考虑DP[i][j]DP[i][j]DP[i][j]:表示当鸟在(i,j)(i,j)(i,j)时点击屏幕的最少次数
1.鸟是从i-1掉下来的
DP[i][j]=DP[i−1][j+y[i]](j+y[i]≤m)DP[i][j]=DP[i-1][j+y[i]](j+y[i]≤m)DP[i][j]=DP[i−1][j+y[i]](j+y[i]≤m)
2.鸟是前面i-1多次点击上来的
DP[i][j]=DP[i−1][j−x[i]∗k](j≥x[i]∗k)DP[i][j]=DP[i-1][j-x[i]*k](j≥x[i]*k)DP[i][j]=DP[i−1][j−x[i]∗k](j≥x[i]∗k)
此时思考时间复杂度O(nmk)O(nmk)O(nmk),肯定TLE
那么就可以将这种情况想成前面跳一次,然后自己往上竖直跳k-1次
DP[i][j]=min(DP[i−1][j−x[i]]+1,DP[i][j−x[i]]+1)DP[i][j]=min(DP[i-1][j-x[i]]+1,DP[i][j-x[i]]+1)DP[i][j]=min(DP[i−1][j−x[i]]+1,DP[i][j−x[i]]+1)
3.注意当往上跳过m的时候,鸟就一直在m处往后飞
4.因为x可能会有限制水管,所以算完后把水管赋值成INF,就可以了


其实这道题就是一个很板的背包问题,加一点点优化就可以了

代码实现

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define MAXM 2005
#define MAXN 10005
#define INF 0x3f3f3f3f
int n, m, k;
bool flag[MAXN];
int x[MAXN], y[MAXN];
int low[MAXN], high[MAXN];
int dp[MAXN][MAXM];int main() {scanf ( "%d %d %d", &n, &m, &k );for ( int i = 1;i <= n;i ++ )scanf ( "%d %d", &x[i], &y[i] );for ( int i = 1;i <= k;i ++ ) {int P, H, L;scanf ( "%d %d %d", &P, &L, &H );flag[P] = 1;low[P] = L;high[P] = H;}memset ( dp, 0x3f, sizeof ( dp ) );for ( int i = 1;i <= m;i ++ )dp[0][i] = 0;for ( int i = 1;i <= n;i ++ ) {for ( int j = x[i] + 1;j <= m + x[i];j ++ )dp[i][j] = min ( dp[i - 1][j - x[i]] + 1, dp[i][j - x[i]] + 1 );for ( int j = m;j <= m + x[i];j ++ )dp[i][m] = min ( dp[i][m], dp[i][j] );for ( int j = 1;j + y[i] <= m;j ++ )dp[i][j] = min ( dp[i][j], dp[i - 1][j + y[i]] );if ( flag[i] ) {for ( int j = 1;j <= low[i];j ++ )dp[i][j] = INF;for ( int j = high[i];j <= m;j ++ )dp[i][j] = INF;}}int result = INF;for ( int i = 1;i <= m;i ++ )result = min ( result, dp[n][i] );if ( result < INF )printf ( "1\n%d", result );else {int i, j, tot = 0;for ( i = n;i >= 1;i -- ) {for ( j = 1;j <= m;j ++ )if ( dp[i][j] < INF )break;if ( j <= m )break;}for ( int j = 1;j <= i;j ++ )if ( flag[j] )tot ++;printf ( "0\n%d", tot );}return 0;
}

Star Way To Heaven (prim最小生成树) // [ NOIP提高组 2014]飞扬的小鸟(DP)相关推荐

  1. 【NOIP2014提高组】飞扬的小鸟

    题目背景 NOIP2014 提高组 Day1 试题. 题目描述 Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管 ...

  2. [NOIp提高组2014]解方程

    题目大意 求方程 \[ \sum_{i=0}^{n}a_ix^i=0 \] 在\([1,m]\)内的整数解 \(1 \leq |a_i| \leq 10^{10000},a_i\neq 0,1 \le ...

  3. NOIP提高组1580~1590集合答案

    1880:[13NOIP提高组]华容道时间限制: 1000 ms 内存限制: 131072 KB 提交数: 298 通过数: 124 [题目描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才 ...

  4. 2018.12.08【NOIP提高组】模拟B组总结(未完成)

    2018.12.08[NOIP提高组]模拟B组总结 diyiti 保留道路 进化序列 B diyiti Description 给定n 根直的木棍,要从中选出6 根木棍,满足:能用这6 根木棍拼出一个 ...

  5. 第一届『Citric杯』NOIP提高组模拟赛 题解

    [官方题解]第一届『Citric杯』NOIP提高组模拟赛 题解 第一题 柠檬超市 这题是本次模拟赛的送分题.做法显然. 但是注意此题有一个陷阱: 注意W和C的规模都是10^9,所以如果直接用doubl ...

  6. 津津的储蓄计划 NOIp提高组2004

    这个题目当年困扰了我许久,现在来反思一下 本文为博客园ShyButHandsome的原创作品,转载请注明出处 右边有目录,方便快速浏览 题目描述 津津的零花钱一直都是自己管理.每个月的月初妈妈给津津\ ...

  7. 信息学奥赛一本通(C++版)NOIP提高组(1820-1829)

    信息学奥赛一本通(C++版)NOIP提高组目录 //1820 [题目描述] 我们可以用这样的方式来表示一个十进制数:将每个阿拉伯数字乘以一个以该数字所 处位置的(值减1)为指数,以10为底数的幂之和的 ...

  8. {小结}2016.6.11【初中部 NOIP提高组 】模拟赛C

    2016.6.11[初中部 NOIP提高组 ]模拟赛C No.1!!! 100+33.3+10+90=233.3 23333 1298. 牛棚(graze2.pas/c/cpp) 题解 1299. 洗 ...

  9. 6271. 2019.8.4【NOIP提高组A】锻造 (forging)

    6271. 2019.8.4[NOIP提高组A]锻造 (forging)  (File IO): input:forging.in output:forging.out Time Limits: 15 ...

最新文章

  1. 分布式事务中间件 Fescar—RM 模块源码解读
  2. python数据处理pdf百度云_Python数据处理 PDF 高清版
  3. Docker基础之九: 管理容器的数据
  4. Java虚拟机2:Java 运行时数据区
  5. 内网外网同时连接方法
  6. 关于复旦大学英语水平测试和计算机应用能力水平测试成绩记载事宜的说明,复旦大学水平测试(FCT、FET)近期通知概览 | 一周复旦热问...
  7. 安装Python第三方库方法总结
  8. Android开发笔记(十)常用的图片加工操作
  9. python findall函数_Python正则表达式
  10. eclipse设置系统字体
  11. C# sqlDataReader区别Dataset
  12. php+将json转字符串,php实现json转字符串的方法
  13. c语言课程设计挂科率高吗,有没有挂科的人指教下怎么让老师把成绩改高呢???...
  14. DNS flood攻击分析
  15. 苏宁 android面试题,苏宁面试题.doc
  16. Java类和对象知识点的整理
  17. 关于c语言专业名词的意思,c语言重要专业词汇带翻译
  18. 四年了,工作的迷茫。
  19. 20230406英语学习
  20. 字典文件txt下载_QQ阅读软件下载-QQ阅读ios版下载

热门文章

  1. 费马大定理,集惊险与武侠于一体
  2. 巴比伦算法求平方根c语言,巴比伦算法求平方根
  3. php js 复选框选中,为每个选中的复选框显示相同的一组问题。 (PHP和JS / Jquery)...
  4. android studio插入数据表中没有_学Java能拿高薪吗 Java中常见排序算法有哪些
  5. 如何证明服从卡方分布_谈谈抽样分布定理
  6. 开启php的文件上传扩展,linux中如何通过php.ini添加扩展?
  7. mysql 表与表之间的条件比对_值得收藏 | 一份最完整的MySQL规范
  8. office连接oracle,Access(VBA)连接Oracle数据库的代码
  9. oracle拆分分区语法详解大全_Oracle hash的分区方法详解
  10. c++——优先队列(priority_queue)