NOIP2018 普及组复赛题解
本次也是天天快乐编程集训队2021CSP&NOIP赛前训练-赛前适应赛的题目,OI赛制有步骤分,请大家放心书写代码。
2018年一等奖浙江分数线为230分,二等奖分数线为100分,三等奖分数线为80分。
当年附中情况,zxy是163分
对应luogu题目, T1 标题统计、T2 龙虎斗、T3 摆渡车、T4 对称二叉树 ,可以到luogu上查看更多题解。
T1 标题统计 字符串
需要读取一行,即gets或者getline。
判断数字和字母大小写就是满分了
第一题比较送分,一般情况下第一题最简单,是签到题。但是如果第一题比较难,应该先做后面的,比赛时间有限。
正式比赛需要注意这个题目概况,这个题需要我们在相应的文件夹内将文件名命名为title.cpp,并在代码中添加上文件读写。
#include<bits/stdc++.h>
using namespace std;
int main()
{
freopen("title.in","r",stdin);
freopen("title.out","w",stdout);
//你的代码
return 0;
}
T2 龙虎斗 枚举、预处理
枚举,p1位置加s1个工兵,然后依次枚举把s2个工兵放在所有的兵营里,每次算一遍双方势力之差,取最小就可以了
直接枚举,可以得到80分
#include <bits/stdc++.h>
using namespace std;
int n,m, p1, s1, s2;
int a[1000005];
//计算双方势力之差
int cal(int x)
{
//sum1计算左边,sum2计算右边
int sum1 = 0, sum2 = 0;
//先假设位置x加上s2个工兵
a[x] += s2;
for (int i = 1; i <= n; i++)
{
//m号兵营跳过
if (i == m)
continue;
//分左右
else if (i < m)
sum1 += (m - i) * a[i];
else
sum2 += (i - m) * a[i];
}
//再减去s2个,因为是假设加上了s2个工兵
a[x] -= s2;
if (sum1 >= sum2)
return sum1 - sum2;
return sum2 - sum1;
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
scanf("%d%d%d%d", &m, &p1, &s1, &s2);
//加上s1个工兵
a[p1] += s1;
int min = 1e9,ans;
//枚举编号i
for (int i = 1; i <= n; i++)
{
//算一下势力之差
int tmp = cal(i);
//小的话要更新
if (min > tmp)
{
min = tmp;
ans = i;
}
}
printf("%d", ans);
return 0;
}
之前的代码是超时的,因为做法是O(n^2 )的,但是后20%数据是10^5 ,写起来要难写些。而且预处理会爆int,当求和是一定要计算好数据类型是否够用,因为比赛没有OJ帮忙验证。
其实就是做下前缀和
T3 摆渡车 动态规划(高级)
这题比想像得要难,dp[i][j]表示第i个人等了j分钟的最优值 ,
T4 对称二叉树 二叉树
这题反而没想象的那么难,直接dfs就好了
本文来自博客园,作者:暴力都不会的蒟蒻,转载请注明原文链接:https://www.cnblogs.com/BobHuang/p/15333877.html