本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。


文章目录

  • NOIP2018(普及组 ) 赛后感想 & 题解
    • #1. 标题统计
    • #2. 龙虎斗
    • #3. 摆渡车
      • Lemma
    • #4. 对称二叉树
    • #5. 总结

NOIP2018(普及组 ) 赛后感想 & 题解

\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquadby frankchenfu 2018/11/24

#1. 标题统计

近年来普及组第一题的难度的确在逐年下降。这道题主要考察基础的字符操作(或者说是循环语句的使用)。

我们可以考虑每次读入一个字符,如果这个字符是数字或是字母,我们把答案+1+1+1,直到读完(读入EOF)为止。

因此我们可以写出以下代码(title.cpp)。时间复杂度O(n)\text{O}(n)O(n),其中nnn表示输入文件的大小。

#include<cstdio>
#include<cstring>
#include<cctype>
const int MAXN=10;int main(){freopen("title.in","r",stdin);freopen("title.out","w",stdout);int ans=0;    char ch=getchar();while(ch!=EOF){ans+=(isdigit(ch)||isalpha(ch));ch=getchar();}printf("%d\n",ans);return 0;
}

#2. 龙虎斗

我们首先可以把出现在p1p_1p1​兵营的“天降神兵”看作是p1p_1p1​里原有的,这并不影响我们的答案。

接着,我们把轩轩的气势值记为正数,凯凯的记为负数,那么就是求对于某一个点使得加入s2s_2s2​位工兵之后使得双方的气势值之和的绝对值最小。

因此我们可以写出以下代码(fight.cpp)。时间复杂度O(n)\text{O}(n)O(n)。

#include<cstdio>
#include<cstring>
const int MAXN=100010;int n,m,p1;
long long s1,s2;
long long c[MAXN];inline long long my_abs(long long x){return x>0?x:-x;
}
int main(){freopen("fight.in","r",stdin);freopen("fight.out","w",stdout);scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%lld",&c[i]);scanf("%d%d%lld%lld",&m,&p1,&s1,&s2);long long sum=0; for(int i=1;i<=n;i++)sum+=c[i]*(long long)(m-i);sum+=s1*(m-p1); long long ans=(1ll<<60),ans_pos=0;for(int i=1;i<=n;i++){ if(ans>my_abs(sum+s2*(long long)(m-i))){ans=my_abs(sum+s2*(long long)(m-i));ans_pos=i;}}printf("%lld\n",ans_pos);return 0;
}

#3. 摆渡车

传说中让人抓狂的普及组第三题来了,就是这道题让我没有时间去做第444题,导致我惨淡收场。

好吧开始讲题。我们首先考虑如何设计dp的状态。

  • 有一维表示到第iii个人了,这一定是要枚举的。接下来呢?

  • 我们还需要知道每个人在哪个时间出发,于是我们又多了一维。

于是我们设计了一个f(i,j)f(i,j)f(i,j)的状态,表示第iii个人在等待了jjj分钟后出发。

至于为什么是等待的时间呢?因为实际上题目要求的是等待的时间,并非出发的时间,因此只与每个人等待的时间有关;另一方面,由于时间ttt过大,空间无法承受,因此只能够将等待时间记入状态——当然这不影响答案。

所以等待的时间需要记多大的范围呢?

Lemma

对于每一个人,等待的时间一定在[0,m)[0,m)[0,m)之间。

Proof. 对于一个人如果等待了km+t(k∈N*)km+t(k\in \text{N*})km+t(k∈N*)的时间,则一定是等待别人一起拼车(否则他就自己走了)。那么如果他选择在(k−1)m+t(k-1)m+t(k−1)m+t的时间就出发了,那么他所等待的朋友一定可以在km+tkm+tkm+t的时间上车,而他自己却节省了mmm的等待时间,因此对于一个人,他只可能等待000到m−1m-1m−1分钟。

所以我们第二维状态只需要记O(m)O(m)O(m)的大小。总的空间复杂度O(nm)O(nm)O(nm)。

接下来考虑转移。

我们枚举iii,设从第j+1j+1j+1个人开始都和iii拼车,并且jjj推迟了ggg分钟出发,那么iii出发的时间t=min⁡(ai,(aj+g)+m)t=\min(a_i,(a_j+g)+m)t=min(ai​,(aj​+g)+m)。由此可以推出转移方程:

(注:其中ttt就是算出来的出发时间,推出当第j+1j+1j+1个人开始都与iii拼车,第jjj个人推迟ggg分钟出发的最优答案)
f(i,t−ai)=∑k=j+1it−ak=(i−j)⋅t−∑k=j+1iak\begin{matrix} f(i,t-a_i)&amp;=&amp;\displaystyle\sum_{k=j+1}^{i}t-a_k\\&amp;=&amp;(i-j)\cdot t-\displaystyle\sum_{k=j+1}^{i}a_k \end{matrix} f(i,t−ai​)​==​k=j+1∑i​t−ak​(i−j)⋅t−k=j+1∑i​ak​​

其中∑ak\sum a_k∑ak​是可以前缀和预处理的,因此我们只需要枚举i,j,gi,j,gi,j,g即可。答案是min⁡j=0m−1f(n,j)\min_{j=0}^{m-1}f(n,j)minj=0m−1​f(n,j)

时间复杂度O(n2m)O(n^2m)O(n2m)。然后这道题就结束了。

(偷偷告诉你,实际上如果你忘了前缀和,写出了O(n3m)O(n^3m)O(n3m)的做法也是可以过的哦。NOIP实测可过。)

那我就把我考场上写的复杂度不太对但是满分的代码贴上来咯还是贴复杂度正确的吧(bus.cpp):

#include<cstdio>
#include<cstring>
#include<algorithm>
const int MAXN=510;int n,m,a[MAXN];
long long f[MAXN][110];
long long sum[MAXN];inline int max(int x,int y){return x>y?x:y;
}
inline long long min(long long x,long long y){return x<y?x:y;
}int main(){scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%d",&a[i]);std::sort(a+1,a+n+1);for(int i=1;i<=n;i++){sum[i]=sum[i-1]+a[i];for(int g=0;g<m;g++){long long wt=0;for(int k=1;k<=i;k++)wt+=a[i]+g-a[k];f[i][g]=wt;}for(int j=1;j<i;j++)for(int g=0;g<m;g++){int t=max(a[j]+m+g,a[i]);int lst=t-a[i];long long wt=(i-j)*(long long)t-(sum[i]-sum[j]);f[i][lst]=min(f[i][lst],f[j][g]+wt);}}long long _ans=(1ll<<60);for(int i=0;i<m;i++)_ans=min(_ans,f[n][i]);printf("%lld\n",_ans);return 0;
}

#4. 对称二叉树

由于第三题的缘故我没想到这道题怎么做。其实挺简单的。就是先算出每棵子树的大小,然后挨个判断。

判断方法:每次比较两颗子树,设根节点分别为l,rl,rl,r。

  • 要判断两个大小是不是相等。
  • 要判断权值是不是相等。
  • 然后判断直接连接的结构是不是对称——即比较l.lsonl.lsonl.lson和r.rsonr.rsonr.rson是同时存在;l.rsonl.rsonl.rson和r.lsonr.lsonr.lson是同时存在。
  • 如果都满足,那么表示他们在目前这个深度上对称,递归比较l.lsonl.lsonl.lson和r.rsonr.rsonr.rson、l.rsonl.rsonl.rson和r.lsonr.lsonr.lson即可。
  • 如果全部满足,则就是对称二叉树。

因此,我们可以枚举每个点,然后递归判断以它为根的子树,初始的时候比较i.lsoni.lsoni.lson和i.rsoni.rsoni.rson。

容易看出,由于有结构比较上的剪枝,因此最坏情况就是满二叉树和完全二叉树。这个时候判断的次数是O(log⁡2n)O(\log_2 n)O(log2​n) 层的。因此总的复杂度就是O(nlog⁡2n)O(n \log_2 n)O(nlog2​n)。实际上几乎跑不满,因此10610^6106数据还是能过的。

代码如下(tree.cpp):

#include<cstdio>
#include<cstring>
const int MAXN=1000010;
int n,lson[MAXN],rson[MAXN];
int w[MAXN],sz[MAXN];void dfs(int u){sz[u]=1;if(~u[lson]){dfs(u[lson]);sz[u]+=sz[u[lson]];}if(~u[rson]){dfs(u[rson]);sz[u]+=sz[u[rson]];}
}bool check(int l,int r){if((~l)&&(~r)){if(w[l]!=w[r]||sz[l]!=sz[r])return 0;return check(l[lson],r[rson])&&check(l[rson],r[lson]);}else if((~l)|(~r))return 0;elsereturn 1;
}int main(){scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&w[i]);for(int i=1;i<=n;i++)scanf("%d%d",&i[lson],&i[rson]);dfs(1);int ans=0;for(int i=1;i<=n;i++)if(sz[i]>ans&&check(i[lson],i[rson]))ans=sz[i];printf("%d\n",ans);return 0;
}

#5. 总结

​ 这一年感觉对于dp与搜索方面的训练是有效果的,尤其是考场上推出了第三题,感觉还是蛮有成就感的。但是代码熟练度还是不够,经常会犯一些小的错误,导致写不顺,最后没时间打第4题,还是能力有欠缺吧。希望以后思维上能有提高,不要让这种题目一题卡上2个小时。最后一次普及组之旅,还算是满意吧。

NOIP2018(普及组 ) 赛后感想 题解相关推荐

  1. 信息学奥赛一本通 1981:【18NOIP普及组】对称二叉树 | 洛谷 P5018【NOIP2018 普及组】 对称二叉树

    [题目链接] ybt 1981:[18NOIP普及组]对称二叉树 洛谷 P5018[NOIP2018 普及组] 对称二叉树 [题目考点] 二叉树 [解题思路] 先求出二叉树中各子树的结点数 遍历二叉树 ...

  2. 信息学奥赛一本通 1979:【18NOIP普及组】龙虎斗 | 洛谷 P5016 [NOIP2018 普及组] 龙虎斗

    [题目链接] ybt 1979: [18NOIP普及组]龙虎斗 洛谷 P5016 [NOIP2018 普及组] 龙虎斗 [题目考点] 1. long long类型使用 已知变量a, b是int类型的变 ...

  3. 信息学奥赛一本通 1978:【18NOIP普及组】标题统计 | 洛谷 P5015 [NOIP2018 普及组] 标题统计

    [题目链接] ybt 1978:[18NOIP普及组]标题统计 洛谷 P5015 [NOIP2018 普及组] 标题统计 [题目考点] 1. 字符串 读入带空格的字符串 将带空格的字符串读入字符数组 ...

  4. P1199(NOIP2010 普及组)三国游戏 题解

    P1199(NOIP2010 普及组)三国游戏题解 Step-1 输入(重点) 输入n:int n;cin>>n; 输入数组: int a[1001][1001]; for(int i=1 ...

  5. P1010 [NOIP1998 普及组] 幂次方 题解

    P1010 [NOIP1998 普及组] 幂次方 题解 题目描述 任何一个正整数都可以用 2 的幂次方表示.例如 137 = 2 7 + 2 3 + 2 0 . 137=2^7+2^3+2^0. 13 ...

  6. P5017 NOIP2018 普及组 摆渡车

    P5017 NOIP2018 普及组 摆渡车 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 显然要把人按照到达时间排序.然后考虑 dp. 设 \(f(i)\) 表示前 \(i\) ...

  7. NOIP2018普及组初赛题解

    展开全文 第24届全国青少年信息学奥林匹克联赛初赛 普及组C++语言试题 竞赛时间:2018 年 10 月 13 日 14:30~16:30 选手注意: 1.试题纸共有 7 页,答题纸共有 2 页,满 ...

  8. [NOIP2010 普及组] 三国游戏 题解

    一只蒟蒻,第一次写题解,有错误还望指正! [NOIP2010 普及组] 三国游戏 题目https://www.luogu.com.cn/problem/P1199 题意理解 废话不多说,我们先看题目. ...

  9. 2012-2018普及组第一题题解

    noip2018 标题统计 [题目描述] 凯凯刚写了一篇美妙的作文,请问这篇作文的标题中有多少个字符? 注意:标题中可能包含大.小写英文字母.数字字符.空格和换行符.统计标题字符数时,空格和换行符不计 ...

最新文章

  1. 使用R语言分析微信好友
  2. iOS-开发记录-UIView属性
  3. java多线程系列:通过对战游戏学习CyclicBarrier
  4. CloudFoundry和AWS上应用监听的端口号
  5. 开发工具MyEclipse如何支持可视化设计HTML和JSP页面
  6. Java函数式编程和面向对象编程
  7. python socketio_python3--socketIO_client 摸索怕坑指南
  8. Oracle数据库链路
  9. 贪吃蛇大作战游戏攻略
  10. 无传感FOC控制中的转子位置和速度确定方法一
  11. 互斥机制synchronized学习
  12. 正确区分标识(zhi)符、关键字与保留字
  13. Ubuntu系统下 .7z 文件压缩解压命令
  14. android的listview分组显示的时候layout_marginTop失效的解决办法
  15. 移动支付清算平台介绍
  16. 怎么从主机拷贝文件到虚拟机
  17. UiPath 安装与下载
  18. “低代码,零代码,APAAS”是什么?怎么选?
  19. YesDev项目管理,专注研发产能提升。从现在起,走向卓越
  20. STM8S003F3通过PWM波实现三基色呼吸灯(转)

热门文章

  1. ggplot作图显示中文
  2. 推荐10个实用的日常开发和写作必备工具
  3. dw中css目标规则命名,css 常用样式命名规则
  4. css防止高度塌陷,css之高度塌陷及其解决方法
  5. 电脑电量为0,显示已接通,却充不上电
  6. python预测子女身高_Python 孩子身高预测
  7. 天正双击墙体不能编辑_【插件辅助下BIM正向设计】天正建筑 VS Revit
  8. python寻峰算法_python/scipy的寻峰算法
  9. 【无标题】JAVA解压ZIP文件并解析Excel(easyExcel)
  10. Photoshop Elements 2023(PSE简化版2023) 支持win/mac版