第一届『Citric杯』NOIP提高组模拟赛 题解
【官方题解】第一届『Citric杯』NOIP提高组模拟赛 题解
第一题 柠檬超市
这题是本次模拟赛的送分题。做法显然。
但是注意此题有一个陷阱:
注意W和C的规模都是10^9,所以如果直接用double来存储性价比会挂精度(999999999/1000000000和999999998/999999999的差距只有10^-18,这么微小的差距double是分辨不出来的)
正确做法是,把除法的除数移项,转化成乘法,然后用int64或long long。
另外一个讨巧的方法是用long double或extended来存储性价比,因为long double/extended的有效数字比double更多,所以勉强能不挂精度。
很不幸,如果挂精度的话就只有20分了。
需要的知识:模拟
代码长度 小于0.5KB.
第二题 柠檬的坦克游戏
此题20%数据的做法显然,直接照着题目要求模拟即可,O(N^3)
此题40%数据做法也比较简单,有两个做法:
1.对20%的做法进行改进,预先对所有的武器按D值排序,这样查找有没有更优的武器时直接查找D值比它大的就行了,时间复杂度可以证明被均摊到了O(N^2)。
2.依然预先对所有武器按D值从小到大排序,然后每次扫一遍,用一个单调栈维护即可,只要遇到R值比栈顶大就弹栈,否则入栈。扫一次就能得出一组,也是O(N^2)的。
此题满分做法是对上一个做法的改进。
仔细观察题目的流程,我们可以发现一个更优的做法。
首先我们发现同一组内的武器,按D值从大到小排序后,R值必然也是从小到大的。
而且我们发现,如果一件武器A的D值比另一件武器B的D值大,那么武器B不会影响到武器A的分组。
于是考虑把武器按D值从大到小排序,然后逐个加入武器,并为新加入的武器找到合适的组。因为在新加入一件武器之前,我们已经加入了所有D值更大的武器,而剩下的武器都不会影响当前武器的分组,所以现在得出的组号就是最终的组号。
假设D值最大的前x个武器已经全部加入组,而且现在已经有k组了,定义第i组里最大的R值为maxR(i),那么我们发现maxR(i)必然随i递减。
我们考虑加入第x+1个武器,我们发现,按照题目要求,这件武器必然会加入到第i组,i是最小的让maxR(i)<D成立的i值。
于是我们直接用数组存储所有组的maxR,新加入武器时二分查找到加入位置,然后更新对应的那个maxR即可。
时间复杂度O(NlgN)
需要的知识: 二分查找
代码长度 0.5KB ~ 1KB
第三题 柠檬当上了JC局长!
此题20%数据做法显然,直接爆搜即可。
想要得到更高的分数,首先我们要观察一些性质。
首先,我们发现罪犯的逃跑方式,实际是在给定图的点1的最短路径图上,从根开始,每次随机选择一个孩子移动,移动到叶子后如果还没被抓到就失败了。
而且,题目保证了从结点1到任意结点的最短路唯一,所以点1的最短路径图实际是一棵树!
于是,我们可以先做一次点1为源点的dijkstra或直接floyd,把点1的最短路径树建立出来。
然后问题就变成了,给定一棵树,你可以在树的结点上设置埋伏,以获得最高的抓捕成功几率。
我们发现一个非常显然的动态规划状态:dp[i][j]在点i为根的子树内共设置j个**,罪犯到达i后能获得的最高成功率。
那么50%数据的做法就非常显然了。
因为我们保证了任意一个结点度数不超过3,也就是每个结点最多只有2个孩子(根可能有3个孩子,不过这不会影响复杂度)
于是我们转移时,暴力枚举根以及其孩子分别分配到了多少个人进行埋伏。时间复杂度是O(N*P^4)
进一步思考,很容易得出满分做法。
我们发现,在一个结点上所要进行的分配人力的任务,实际是一个背包。于是在结点上做一个背包即可。
但是注意这个背包是以当前结点的所有的孩子做背包,然后因为当前节点抓捕失败后才能往孩子走,所以当前结点要枚举埋伏人数,才能得出最终的答案。
时间复杂度是O(N*P^2)
需要的知识:最短路径算法、最短路径树的概念、背包DP、树形DP
代码长度 1KB~2KB
数据和标程的下载地址: http://pan.baidu.com/share/link?shareid=3747&uk=2249476017
最后,感谢诸位的参与。感谢Vani,kAc,applepi等人的验题
PS:以上是sillycross大神的官方题解,他写的是pascal,我等c++支持者便是抓瞎,当然,我真的没看他的代码。因为看了也不懂。
以下是我自己写的c++的代码,大神不要BS我啊!
第一题:我这个蒟蒻,一看大水,果断5分钟敲完交了,没想精度问题,果断20分。。
1 #include <cstdio> 2 #include <cstdlib> 3 using namespace std; 4 __int64 ans,n,s,w,c,i,fz=0,fm=1; 5 void read() 6 { 7 scanf("%I64d%I64d",&n,&s); 8 for(i=1;i<=n;i++) 9 { 10 scanf("%I64d%I64d",&w,&c); 11 if(c<=s) 12 { 13 if(fz*c<fm*w) 14 { 15 fz=w; 16 fm=c; 17 ans=i; 18 } 19 } 20 } 21 printf("%I64d",ans); 22 } 23 int main() 24 { 25 read(); 26 system("pause"); 27 return 0; 28 }
第二题:我表示我一看n^2的算法了,懒得写了,直接模拟的,rp不错,骗了30分。其实仔细想想nlogn也不是很难,还是做题缺乏深入思考。跪地。
1 #include <cstdio> 2 #include <cstdlib> 3 #include <algorithm> 4 using namespace std; 5 int n,maxr[100010],cnt,len,num; 6 struct P 7 { 8 int d,r,id,bh; 9 }p[100010]; 10 bool cmp(const P &x,const P &y) 11 { 12 return x.d>y.d; 13 } 14 bool cmp2(const P &x,const P &y) 15 { 16 return x.id<y.id; 17 } 18 void read() 19 { 20 scanf("%d",&n); 21 for(int i=1;i<=n;i++) 22 { 23 scanf("%d%d",&p[i].d,&p[i].r); 24 p[i].id=i; 25 } 26 sort(p+1,p+1+n,cmp); 27 } 28 void go() 29 { 30 len=1; 31 maxr[len]=p[1].r; 32 p[1].bh=1; 33 for(int i=2;i<=n;i++) 34 { 35 if(p[i].r<maxr[len]) 36 { 37 len++; 38 maxr[len]=p[i].r; 39 p[i].bh=len; 40 } 41 else 42 { 43 int l=1,r=len; 44 while(l<=r) 45 { 46 int mid=(l+r)>>1; 47 if(maxr[mid]<p[i].r) num=mid,r=mid-1; 48 else l=mid+1; 49 } 50 maxr[num]=p[i].r; 51 p[i].bh=num; 52 } 53 } 54 sort(p+1,p+1+n,cmp2); 55 for(int i=1;i<=n;i++) printf("%d\n",p[i].bh); 56 } 57 int main() 58 { 59 read(); 60 go(); 61 system("pause"); 62 return 0; 63 }
第三题:到晚体觉得肚子疼,于是乎去厕所蹲了一会儿,突然来了灵感,发现这是一棵树,因为周克华走的永远是最短路,而spfa可以记录最短路的前继,利用这个前继来建树,剩下的就是树形DP+背包了。。可惜概率算错了。。就得了30分。。继续跪!
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <iostream> 5 using namespace std; 6 int n,m,cnt=1,a,b,c,start,h,t,head[220],next[20020],to[20020],len[20020],s,dis[220],que[500200]; 7 double dp[220][220],jl[220][220],f[220]; 8 bool vis[220]; 9 int pre[220],son[220]; 10 void add(int v,int u,int w) 11 { 12 len[cnt]=w; to[cnt]=u; next[cnt]=head[v]; head[v]=cnt++; 13 } 14 void read() 15 { 16 scanf("%d%d",&n,&m); 17 for(int i=1;i<=m;i++) 18 { 19 scanf("%d%d%d",&a,&b,&c); 20 add(a,b,c); add(b,a,c); 21 } 22 scanf("%d",&s); 23 for(int i=1;i<=n;i++) 24 for(int j=1;j<=s;j++) 25 scanf("%lf",&jl[i][j]); 26 } 27 void spfa() 28 { 29 start=1; 30 memset(dis,0x3f,sizeof dis); 31 h=1;t=2; 32 que[1]=start; 33 vis[start]=true; 34 dis[start]=0; 35 while(h<t) 36 { 37 int sta=que[h++]; 38 vis[sta]=false; 39 for(int i=head[sta];i;i=next[i]) 40 { 41 if(dis[to[i]]>dis[sta]+len[i]) 42 { 43 dis[to[i]]=dis[sta]+len[i]; 44 pre[to[i]]=sta; 45 if(vis[to[i]]==false) 46 { 47 vis[to[i]]=true; 48 que[t++]=to[i]; 49 } 50 } 51 } 52 } 53 } 54 void create() 55 { 56 memset(head,0,sizeof head); 57 cnt=1; 58 for(int i=2;i<=n;i++) 59 add(pre[i],i,1); 60 for(int i=1;i<=n;i++) 61 for(int j=head[i];j;j=next[j]) 62 son[i]++; 63 } 64 void dfs(int u) 65 { 66 for(int i=1;i<=s;i++) dp[u][i]=jl[u][i]; 67 if(head[u]==0) return; 68 69 for(int i=head[u];i;i=next[i]) dfs(to[i]); 70 for(int i=0;i<=s;i++) f[i]=0.0; 71 72 for(int i=head[u];i;i=next[i]) 73 for(int j=s;j>=0;j--) 74 for(int k=0;k<=j;k++) 75 f[j]=max(f[j],f[j-k]+dp[to[i]][k]); 76 77 for(int i=0;i<=s;i++) f[i]=f[i]/double(son[u]); 78 for(int i=0;i<=s;i++) 79 for(int j=0;j+i<=s;j++) 80 dp[u][i+j]=max(dp[u][i+j],f[j]*(1.0-jl[u][i])+jl[u][i]); 81 } 82 void gogo() 83 { 84 dfs(1); 85 printf("%.4lf",dp[1][s]); 86 } 87 void go() 88 { 89 spfa(); 90 create(); 91 gogo(); 92 } 93 int main() 94 { 95 read(); 96 go(); 97 return 0; 98 }
总体来说这套题的难度还是低于NOIP的,(这么低分,你也好意思说!),应该得到的教训就是,简单题只要做了就必须拿满分!还有就是,思考完善了再动手敲代码!
转载于:https://www.cnblogs.com/proverbs/archive/2012/08/21/2648920.html
第一届『Citric杯』NOIP提高组模拟赛 题解相关推荐
- 第二届『Citric杯』NOIP提高组模拟赛
一道防AK的好题 不得不吐槽这个题目背景和算法.这就是一脑筋急转弯啊. Code program hard; CONST FileName='hard'; var n,i,tot:longint;x, ...
- 兰州大学第一届『飞马杯』程序设计竞赛(同步赛),签到题ACFHJ
序 题号 标题 通过率 我的状态 A ★★比赛新机制★★ 309/1537 通过 (找规律+前缀和维护) (longlong记得开1e18,我1e15WA了一个多小时) B ★★体育课排队★★ 1/1 ...
- 【洛谷】NOIP提高组模拟赛Day2【动态开节点/树状数组】【双头链表模拟】
U41571 Agent2 题目背景 炎炎夏日还没有过去,Agent们没有一个想出去外面搞事情的.每当ENLIGHTENED总部组织活动时,人人都说有空,结果到了活动日,却一个接着一个咕咕咕了.只有不 ...
- NOIP2017提高组模拟赛4 (总结)
NOIP2017提高组模拟赛4 (总结) 第一题 约数 设K是一个正整数,设X是K的约数,且X不等于1也不等于K. 加了X后,K的值就变大了,你可以重复上面的步骤.例如K= 4,我们可以用上面的规则产 ...
- 计蒜客2020蓝桥杯大学A组模拟赛题解
计蒜客2020蓝桥杯大学A组模拟赛题解 蓝桥杯的话,去年拿了C++组的国二.今年报名了新成立的Python组,不知道能不能摸到国一的鱼 模拟赛链接如下: https://www.jisuanke.co ...
- 兰州大学第一届『飞马杯』程序设计竞赛 - ★★平形四边行★★(鸽巢原理+暴力)
题目链接:点击查看 题目大意:二维平面坐标系上给出 nnn 个点,现在需要求出四个点,满足四个点可以组成可退化的平行四边形 题目分析:因为坐标的范围很小,所以瞬间想到了上周刷到的一道题目的模型: Co ...
- 兰州大学第一届『飞马杯』程序设计竞赛 - ★★飞马祝福语★★(动态dp)
题目链接:点击查看 题目大意:给出一个长度为 nnn 的字符串 sss ,现在有 mmm 次操作,每次操作可以修改 [l,r][l,r][l,r] 内的字符为 chchch,问每次修改之后的字符串内含 ...
- 兰州大学第一届『飞马杯』程序设计竞赛 - ★★体育课排队★★(二分+最大流)
题目链接:点击查看 题目大意:给出 nnn 个人,再给出 nnn 个指定位置,每个人每秒钟可以向上下左右四个方向移动一个单位,问最少需要多长时间,才能使所有人都到达指定位置 题目分析:数据比较小,可以 ...
- JZOJ 5850. 【NOIP提高组模拟2018.8.25】e
Description Input Output Sample Input 5 7 0 1 2 3 4 5 1 2 2 3 2 4 1 5 1 2 4 5 2 2 4 5 3 2 4 5 4 2 4 ...
最新文章
- 英特尔cpu发布时间表_英特尔第11代桌面CPU将会支持PCIe4.0,Z490主板或可支持PCIe4.0...
- 关于SQL漏洞注入(Ado.Net)
- python3 装饰器_Python3 装饰器
- react: menuService
- C#基础巩固之基础类型
- DeepMind论文解读:让机器更深入地理解文本
- postgresql主从备份_PostgreSQL主从流复制与手动主备切换架构
- bp神经网络训练_数据分析模型6——神经网络基础(人工智能的底层模型)
- Python中Dict的查找
- Windows 7 / Windows 10 安装 IPX/SPX
- 《设计模式详解》行为型模式 - 命令模式
- f1ag_1s_h3re.php,攻防世界XCTF-WEB-新手练习区(1-3)
- R语言︱list用法、批量读取、写出数据时的用法
- 【python练习题01】字符串格式化输出
- 【HEVC学习与研究】46、HEVC参考代码中SAO的实现
- Java面试题!mysql格式化查询结果
- ios 微信登录sdk集成
- 347. Top K Frequent Elements
- iPad/iPhone与电脑共享文件
- grafana+prometheus监控Springboot服务
热门文章
- 萘酞菁(VONcs),齐岳生物供应各种酞菁化合物材料
- 解决matplotlib绘制图片时plt.savefig()后图片全黑的问题
- Lync 客户端无法及时更新!
- 2021 An Updated Comparison of Four Low Earth Orbit Satellite Constellation Systems to Provide Global
- js获取指定字符后面的字符
- Windows小技巧 -- 命令行窗口打开指定目录的资源管理器
- 编程中的命名方式和常用命名名称
- 计算机组成原理基础知识试题及答案,[电脑基础知识]计算机组成原理试题库.doc...
- 实用经验 92 区分函数模版与模版函数,类模版和模板类
- 用 python 快速「卡通化」人物头像