NOIP2018普及组复赛解析
T1:标题统计
题目大意
输入一个字符串,求字符串除了空格的字符个数
解题思路
这种考你会不会编程的题不会?
code
#include<cstdio>
#include<string>
#include<iostream>
using namespace std;
int ans;
string c;
int main()
{getline(cin,c);int l=c.size();for(int i=0;i<l;i++)ans+=(c[i]!=' '&&c[i]!='\n');printf("%d",ans);
}
T2:龙虎斗
题目大意
一个长度为n序列,被中间点m分成两半,m左边和m右边。
左边战斗力为
∑i=1m−1(m−i)∗ai\sum_{i=1}^{m-1}(m-i)*a_ii=1∑m−1(m−i)∗ai
∑i=m+1n(i−m)∗ai\sum_{i=m+1}^{n}(i-m)*a_ii=m+1∑n(i−m)∗ai
找到一个数值加s2s2s2,使两边的战斗力之差最小
解题思路
先处理好两边战斗力
暴力枚举位置。注意要用longlong
code
#include<cstdio>
#include<algorithm>
#define N 100010
#define lls long long
using namespace std;
lls n,c[N],m,p1,s1,s2,ans1,ans2,mins,mark;
int main()
{scanf("%lld",&n);for(lls i=1;i<=n;i++)scanf("%lld",&c[i]);scanf("%lld%lld%lld%lld",&m,&p1,&s1,&s2);c[p1]+=s1;for(lls i=1;i<m;i++)ans1+=c[i]*(m-i);for(lls i=m+1;i<=n;i++)ans2+=c[i]*(i-m);mark=0;mins=1e19;for(lls i=1;i<m;i++){if(abs(ans1+s2*(m-i)-ans2)<mins){mark=i;mins=abs(ans1+s2*(m-i)-ans2);}}for(lls i=m+1;i<=n;i++){if(abs(ans1-ans2-s2*(i-m))<mins){mark=i;mins=abs(ans1-ans2-s2*(i-m));}}if((mins==abs(ans1-ans2)&&mark<m)||mins<abs(ans1-ans2)) printf("%lld",mark);else printf("%lld",m);
}
T3:摆渡车
题目大意
n个人,有不同的到达时间。一辆车,来回一次要mminm\ \ minm min。安排一个来回时间,使所有人等待时间之和最小。
解题思路
我们可以发现m很小可是t却很大。所有我们不一定要从t入手。因为一个人会影响到他的只有之前的m−1minm-1\ \ minm−1 min。
用fi,jf_{i,j}fi,j表示第i个人等了j的等待时间总数。然后我们枚举i和枚举上一班车的最后一个人j。之后枚举那个人等了多久k。我们就可以计算出这个人上车最少等待时间
tj+k+m−tit_j+k+m-t_itj+k+m−ti
然后我们可以更新fi,wf_{i,w}fi,w
fi,w=min{fi,w,fj,k+sj+1,i+(i−j)∗w}f_{i,w}=min\{f_{i,w},f_{j,k}+s_{j+1,i}+(i-j)*w\}fi,w=min{fi,w,fj,k+sj+1,i+(i−j)∗w}
其中用si,js_{i,j}si,j表示i到j的人都等第j个人上车需要的时间
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 510
#define M 210
using namespace std;
int n,m,t[N],s[N][N],f[N][M],ans;
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&t[i]);sort(t+1,t+1+n);for(int i=1;i<n;i++)//预处理sfor(int j=i+1;j<=n;j++)for(int k=i;k<j;k++)s[i][j]+=t[j]-t[k];memset(f,0x3f3f3f3f,sizeof(f));t[0]=-2e9;for(int i=0;i<=m;i++)//初始化{f[0][i]=0;f[1][i]=i;}for(int i=2;i<=n;i++)//dpfor(int j=0;j<i;j++)for(int k=0;k<=m;k++){int w=t[j]+k+m-t[i];if(w>0)f[i][w]=min(f[i][w],f[j][k]+s[j+1][i]+(i-j)*w);else//特判防越界f[i][0]=min(f[i][0],f[j][k]+s[j+1][i]);}ans=2e9;for(int i=0;i<=m;i++)ans=min(ans,f[n][i]);printf("%d\n",ans);
}
T4:对称二叉树
题目大意
一棵n个点的二叉树,每个点有不同的权值。一棵树对称就是整棵树的左右子节点互换之和长的和之前一样。求这棵树上最大的一颗对称二叉树。
解题思路
对于每个点我们给他两个特征值
z1i=lsoni∗2+rsoni+wi∗4z1_i=lson_i*2+rson_i+w_i*4z1i=lsoni∗2+rsoni+wi∗4
z2i=lsoni+rsoni∗2+wi∗4z2_i=lson_i+rson_i*2+w_i*4z2i=lsoni+rsoni∗2+wi∗4
lson:这个点有没有左子节点
rson:这个点有没有右子节点
然后先左后右的跑一边,记录跑到的点的z1和这颗子树包含的范围。
再先右后左的跑一边,记录跑到的点的z2和这颗子树包含的范围。
之后对于每个节点用字符串hash判断一下z1对于范围是否和z2对应范围相等,如果相等那么这棵子树就是一颗对称二叉树。
时间负责度:O(n)O(n)O(n)
code
#include<cstdio>
#include<algorithm>
#define N 1000010
#define p 10007
#define ull unsigned long long
using namespace std;
int sz[N],a1[N],b1[N],e1[N],a2[N],b2[N],e2[N],z[N],f[N];
int maxs,n,tot,ls[N],rs[N],w[N];
ull hash1[N],hash2[N],pows[N];
void read(int &x)
{char c;bool flag=false;while(c=getchar())if((c>='0'&&c<='9')||c=='-') break;if(c!='-')x=c-48;else flag=true;while(c=getchar())if(c>='0'&&c<='9') x=x*10+c-48;else break;if(flag) x=-x;
}
void dfs1(int x)
{sz[x]=1;a1[++tot]=z[x];b1[x]=tot;if(ls[x]!=-1)dfs1(ls[x]);if(rs[x]!=-1)dfs1(rs[x]);sz[x]+=sz[ls[x]]+sz[rs[x]];e1[x]=tot;
}
void dfs2(int x)
{if(x==-1) return;a2[++tot]=f[x];b2[x]=tot;if(rs[x]!=-1)dfs2(rs[x]);if(ls[x]!=-1)dfs2(ls[x]);e2[x]=tot;
}
ull hash1z(int l,int r)
{return hash1[r]-hash1[l-1]*pows[r-l+1];}
ull hash2z(int l,int r)
{return hash2[r]-hash2[l-1]*pows[r-l+1];}
bool check(int x)
{if(sz[ls[x]]!=sz[rs[x]]) return false;int l1=b1[x],r1=e1[x],l2=b2[x],r2=e2[x];if(hash1z(l1,r1)==hash2z(l2,r2)) return true;return false;
}
int main()
{read(n);for(int i=1;i<=n;i++)read(w[i]);for(int i=1;i<=n;i++){read(ls[i]);read(rs[i]);//fa[ls[i]]=fa[rs[i]]=i;z[i]=((ls[i]!=-1)<<1)+(rs[i]!=-1)+w[i]*4;f[i]=((rs[i]!=-1)<<1)+(ls[i]!=-1)+w[i]*4;//计算特征值}dfs1(1);//正搜tot=0;dfs2(1);//反搜pows[0]=1;for(int i=1;i<=n;i++){pows[i]=pows[i-1]*p;hash1[i]=hash1[i-1]*p+a1[i];hash2[i]=hash2[i-1]*p+a2[i];}//字符串哈希for(int i=1;i<=n;i++)//枚举节点if(check(i))//判断相等maxs=max(maxs,sz[i]);printf("%d",maxs);
}
NOIP2018普及组复赛解析相关推荐
- NOIP2018普及组复赛——T3摆渡车
题目描述 有 n n n名同学要乘坐摆渡车从人大附中前往人民大学,第 i i i 位同学在第 t i t_i
- 近年NOIP普及组复赛题目的简单讲解
NOIP2015普及组复赛 整套题都出得不错,难度适中,层次分明 建议同学们在做题的时候还是先在草稿纸上分析,把关键算法的伪代码写出来,然后设计数据进行静态查错,没有问题后再到电脑上敲出代码.实际效率 ...
- 信息学奥赛一本通 1981:【18NOIP普及组】对称二叉树 | 洛谷 P5018【NOIP2018 普及组】 对称二叉树
[题目链接] ybt 1981:[18NOIP普及组]对称二叉树 洛谷 P5018[NOIP2018 普及组] 对称二叉树 [题目考点] 二叉树 [解题思路] 先求出二叉树中各子树的结点数 遍历二叉树 ...
- 信息学奥赛一本通 1979:【18NOIP普及组】龙虎斗 | 洛谷 P5016 [NOIP2018 普及组] 龙虎斗
[题目链接] ybt 1979: [18NOIP普及组]龙虎斗 洛谷 P5016 [NOIP2018 普及组] 龙虎斗 [题目考点] 1. long long类型使用 已知变量a, b是int类型的变 ...
- 信息学奥赛一本通 1978:【18NOIP普及组】标题统计 | 洛谷 P5015 [NOIP2018 普及组] 标题统计
[题目链接] ybt 1978:[18NOIP普及组]标题统计 洛谷 P5015 [NOIP2018 普及组] 标题统计 [题目考点] 1. 字符串 读入带空格的字符串 将带空格的字符串读入字符数组 ...
- NOIP 2012 普及组 复赛 culture 文化之旅
NOIP 2012 普及组 复赛 culture 文化之旅 1.找寻迪杰斯特拉(Dijkstra)算法,难度适中,过程中,找到该题. 2.结合题意,弄懂输入输出样例是关键一步. 3.为了能解决2,纸笔 ...
- NOIP2009 普及组 复赛 poly 多项式输出
NOIP2009 普及组 复赛 poly 多项式输出 //洛谷 p1067 多项式输出 //难度:普及- //考点:输入,输出 ,输出格式按要求进行处理 //适用:小学生 //陷阱:要注意的条件比 ...
- P5017 NOIP2018 普及组 摆渡车
P5017 NOIP2018 普及组 摆渡车 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 显然要把人按照到达时间排序.然后考虑 dp. 设 \(f(i)\) 表示前 \(i\) ...
- NOIP 2010 普及组 复赛 sanguo 三国游戏
NOIP 2010 普及组 复赛 sanguo 三国游戏 1.扫到他人讨论,取第2大值,且小涵必胜. 2.编码,样例通过,提交,只通过了测试点1,6. 3.看了题解,发现是武将配对中,找出配对的第2大 ...
最新文章
- MySQL中改变相邻学生座位_力扣——换座位(数据库的题
- android内存池,两种常见的内存管理方法:堆和内存池
- 实验室管理好助手——Bio-lab
- 在什么时候才会用到fireEvent方法呢?
- 命名空间中不存在名称_原木定制中不开裂的木材真的存在吗?
- Salt 系统初始化
- (09)Vivado IO约束
- STL的基本函数笔记
- apache+php+mysq环境详细l配置
- 用户故事 | 刷算法面试题的4种思考方式
- r语言如何下载carzip包本地安装_R语言中如何在Mac下快速下载和安装包
- 直升机救援机制的发展
- matlab 蜗杆轮廓,基于MATLAB的直廓环面蜗杆的可视化
- 02组团队项目-Alpha冲刺-4/6
- 如何设计高品质LoRa无线模块
- 哲理故事与管理之道 14 如何留住员工
- 进程和线程的主仆问题
- linux把光标移到文件开头的命令,linux操作命令总结,希望可以帮助到菜鸟
- Dynamics 365 CRM 接入统一身份认证平台(单点登录集成)
- python求三角形面积步骤_Python3计算三角形的面积代码
热门文章
- 新编计算机英语第六章,新编计算机英语-电子教案.ppt
- abb限位开关已打开drv1_广告雕刻机限位开关触发
- java 生成jar_java如何生成jar
- 用gis打开tif格式_如何下载SHP矢量格式的等高线
- php用ajaxs上传图片_jquery+ajax+php 图片上传
- python判断列表是否为空_Jinja2: 判断返回的列表是否为空
- java读取文件跳过_在Java中读取文本文件-为什么跳过行?
- leetcode206. 反转链表
- LeetCode 82 删除排序链表中的重复元素||-中等
- dptcpp 题目 2352: [信息学奥赛一本通-T1440]数的划分-dp