NOIP普及组复赛真题题解及详细答案(经典真题)_第1页
NOIP普及组复赛真题题解及详细答案(经典真题)_第2页
NOIP普及组复赛真题题解及详细答案(经典真题)_第3页
NOIP普及组复赛真题题解及详细答案(经典真题)_第4页
NOIP普及组复赛真题题解及详细答案(经典真题)_第5页
已阅读5页,还剩3页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

NOIP普及组复赛真题题解及详细答案(经典真题)本次整理为NOIP普及组复赛全套四道真题,包含题目大意、解题思路、算法分析、完整AC代码、详细答案与易错点解析,内容贴合竞赛实战,适配复赛备考刷题、复盘纠错。所有题解思路通俗易懂,侧重讲解考场思维与得分技巧。第一题数字统计题目大意给定两个正整数L、R,统计区间[L,R]中,数字2出现的总次数。输入:两个整数L、R(1≤L≤R≤10000)输出:一个整数,代表2出现的总次数解题思路本题为基础模拟题,无需复杂算法。核心思路为遍历区间内每一个数字,逐个拆解数字的每一位,判断是否为2,累计统计数量即可。1.循环遍历L到R的所有整数;2.对每个数,逐位取余、整除,拆解每一位数字;3.若当前位为2,计数器加一;4.遍历结束后输出计数器结果。数据范围极小,暴力模拟完全不会超时,是复赛第一题标准送分题。完整AC代码(C++)PlainText

#include<iostream>

usingnamespacestd;

intmain()

{

intL,R;

cin>>L>>R;

intcnt=0;

for(inti=L;i<=R;i++)

{

intt=i;

while(t>0)

{

if(t%10==2)cnt++;

t/=10;

}

}

cout<<cnt<<endl;

return0;

}样例输入输出与答案解析样例输入:222样例输出:6解析:出现2的数字为2、12、20、21、22。其中2出现次数:2(1次)、12(1次)、20(1次)、21(1次)、22(2次),合计6次。易错点1.忘记统计多位数中多个2的情况(如22、222);2.循环区间写错,写成i<R导致漏掉右端点。第二题接水问题题目大意学校有水槽,有n个水龙头,m个同学依次排队接水。每个同学接水时长固定,每个水龙头同一时间只能一个人接水,前一个人接完下一个人立刻补上。求所有同学接完水的总耗时。输入:第一行两个整数n、m;第二行m个整数,代表每个同学接水的时间。输出:所有同学接水完成的总时间。解题思路本题为贪心模拟题,核心贪心策略:每次让当前剩余接水时间最短的水龙头接待下一位同学。1.初始化n个水龙头的剩余时间,初始全部为0;2.依次遍历每一位同学的接水时间;3.每次找到当前剩余时间最少的水龙头,将当前同学的接水时间累加至该水龙头;4.所有同学分配完毕后,所有水龙头的最大剩余时间即为答案。该策略保证每一步都是最优选择,无多余耗时,完全适配题目数据范围。完整AC代码(C++)PlainText

#include<iostream>

#include<algorithm>

usingnamespacestd;

inta[105];

intmain()

{

intn,m;

cin>>n>>m;

for(inti=1;i<=m;i++)

{

intt;

cin>>t;

intminpos=1;

for(intj=2;j<=n;j++)

{

if(a[j]<a[minpos])minpos=j;

}

a[minpos]+=t;

}

intans=0;

for(inti=1;i<=n;i++)

{

ans=max(ans,a[i]);

}

cout<<ans<<endl;

return0;

}样例输入输出与答案解析样例输入:2513224样例输出:7解析:水龙头1:1+2+4=7水龙头2:3+2=5最大时间为7,即为总耗时。易错点1.最后统计答案时求和而非取最大值;2.查找最小水龙头位置时下标遍历出错。第三题最大乘积题目大意给定一个正整数n,将n拆分为若干个互不相同的正整数之和,使得这些数字的乘积最大,输出最大乘积。输入:一个整数n(1≤n≤100)输出:拆分后的最大乘积解题思路本题为数学贪心题,核心结论:拆分数字尽量从2开始连续累加,保证数字互不相同,且尽可能多拆分,乘积最大。1.从2开始依次累加2、3、4...,直到总和接近n;2.记录剩余差值rest=n-累加和;3.若rest为0,直接累乘所有数;4.若rest不为0,从最大的数开始依次+1,保证数字不重复;5.特殊特判:n=2、n=3时,无法拆分,直接输出自身。数学原理:同等和值下,数字越分散、越接近,乘积越大,且不出现1(1会拉低乘积)。完整AC代码(C++)PlainText

#include<iostream>

#include<vector>

usingnamespacestd;

intmain()

{

intn;

cin>>n;

if(n==2||n==3)

{

cout<<n<<endl;

return0;

}

vector<int>num;

intsum=0;

inti=2;

while(sum+i<=n)

{

num.push_back(i);

sum+=i;

i++;

}

intrest=n-sum;

//从后往前分配余数

for(intj=num.size()-1;j>=0&&rest>0;j--)

{

num[j]++;

rest--;

}

longlongans=1;

for(intx:num)ans*=x;

cout<<ans<<endl;

return0;

}样例输入输出与答案解析样例输入:10样例输出:30解析:最优拆分为2+3+5=10,乘积2×3×5=30。若拆分其他组合,乘积均小于30。易错点1.拆分出现数字1,导致乘积变小;2.未保证数字互不相同,违反题目规则;3.余数从前向后分配,导致数字重复。第四题过河题目大意有一条长度为L的河,河中有若干石子。青蛙每次跳跃距离为S~T之间的整数。青蛙从0位置出发,跳到L位置上岸,求青蛙最少需要踩到多少颗石子。输入:河长度L,跳跃最小距离S、最大距离T,石子数量M,以及M个石子的位置。输出:最少踩踏石子数量。解题思路本题为动态规划+路径压缩经典题,是NOIP普及组压轴高频题。1.状态定义:dp[i]表示跳到位置i时,最少踩到的石子数;2.初始状态:dp[0]=0,其余位置初始化为极大值;3.状态转移:对于每个位置i,遍历所有合法跳跃距离k(S≤k≤T),dp[i]=min(dp[i],dp[i-k]+是否有石子);4.路径压缩:L最大可达1e9,无法直接DP。相邻石子间距超过S*T时,可压缩为S*T,不影响最终答案,大幅降低时间复杂度。完整AC代码(C++)PlainText

#include<iostream>

#include<algorithm>

#include<cstring>

usingnamespacestd;

constintMAXN=10005;

intdp[MAXN];

boolstone[MAXN];

intpos[105];

intmain()

{

intL,S,T,M;

cin>>L>>S>>T>>M;

for(inti=1;i<=M;i++)cin>>pos[i];

sort(pos+1,pos+1+M);

//路径压缩

intlen=0;

intlast=0;

for(inti=1;i<=M;i++)

{

intd=pos[i]-last;

if(d>S*T)d=S*T;

len+=d;

stone[len]=true;

last=pos[i];

}

//终点压缩

if(L-last>S*T)len+=S*T;

elselen+=L-last;

memset(dp,0x3f,sizeof(dp));

dp[0]=0;

for(inti=1;i<=len;i++)

{

for(intk=S;k<=T;k++)

{

if(i-k>=0)

{

dp[i]=min(dp[i],dp[i-k]+(stone[i]?1:0));

}

}

}

cout<<dp[len]<<endl;

return0;

}样例输入输出与答案解析样例输入:102342357样例输出:2解析:青蛙最优跳跃路径:0→3→6→9→10,仅踩踏3、

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论