前言

本来不想写前言的(>人<;)

这只是 mjl 给我们布置的作业,并不是我自己在刷题!

不保证所有代码的正确性,它们仅仅是通过了所有数据点而已。


1.模拟板块

整体难度:红~黄(模拟不会有什么难题 ,别跟我说像猪国杀、儒略日那种)


T1 计算器的改良

AC at 2021-07-31 14:34:08.

难度:黄

解一元一次方程,就是把未知数的系数移到等号左边,常数移到等号右边,然后再除一下就可以了。

我们设置两个变量 \(l,r\),分别代表未知数系数计算后的结果和常数的计算结果。最后模拟就可以了。记得“移项变号”,而且往左移和往右移是相反的,如果写成一样了的可以像我一样在任意一边加一个负号,不影响结果。

不过这个模拟还是有些讲究的。

首先要把整个字符串分为 \(3\) 个部分:等号左边、等号和等号右边。

先遍历等号左边,如果看到数字了就把这个连续是一段数字的字符给转化为整数类型,然后再看这到底是系数还是常数;再再看正负。关于正负可以使用布尔变量来标记。

如果是系数就甩到 \(l\) 变量,是常数就甩到 \(r\) 变量。注意怎么甩,要移项变号。这时候可能要移项也有可能不移,要注意。

遇到减号,把布尔变量设为真。

遇到加号,把布尔变量设为假。(因为我们默认的系数和常数的符号是正,所以加号并没有什么用,只需要布尔变量归零就可以了)

遇到字母特判(经过数字的判断之后,这个字母就是系数为 \(±1\) 的未知数),也需移项变号。

等号右边同理。

记得存未知数的字母,别像我一样最后有一个测试点未知数只在等号右边,但是我处理那一块的时候没写存未知数字母的语句[捂脸]。

废话不多说,上代码。

Code

#include<cstdio>
#include<cstring>
char fh,a[105];
int len,h,l,r;
bool is_fu; //用来判断这个系数 or 常数是不是负数
int main(){
scanf("%s",a+1);
len=strlen(a+1);
//等号左边
for(int i=1;i<=len;i++){
int k=0;
if(a[i]=='='){
h=i+1;
is_fu=0;
break;
}else if(a[i]=='+') is_fu=0;
else if(a[i]=='-') is_fu=1;
else if(a[i]>='0'&&a[i]<='9'){
while(a[i]>='0'&&a[i]<='9'){
k=k*10+a[i]-'0';
i++;
}
i--;
if(a[i+1]>='a'&&a[i+1]<='z'||a[i+1]>='A'&&a[i+1]<='Z'){ //未知数
fh=a[i+1];
if(is_fu){
l-=k;
is_fu=0;
}else l+=k;
}else{ //数字
if(is_fu){
r-=k;
is_fu=0;
}else r+=k;
}
k=0;
}
}
//等号右边
is_fu=0;
for(int i=h;i<=len;i++){
int k=0;
if(a[i]=='+') is_fu=0;
else if(a[i]=='-') is_fu=1;
else if(a[i]>='0'&&a[i]<='9'){
while(a[i]>='0'&&a[i]<='9'){
k=k*10+a[i]-'0';
i++;
}
i--;
if(a[i+1]>='a'&&a[i+1]<='z'||a[i+1]>='A'&&a[i+1]<='Z'){ //未知数
fh=a[i+1];
if(is_fu){
l+=k;
is_fu=0;
}else l-=k;
}else{ //数字
if(is_fu){
r+=k;
is_fu=0;
}else r-=k;
}
k=0;
}
}
printf("%c=%.3lf",fh,-r*1.0/l);
return 0;
}

T2 税收与补贴问题

AC at 2021-08-06 9:44:39.

难度:黄

我寻思着这出题人语文该从小学重修叭。

大概意思就是先让你补全一个价格和购买人数关系的表,然后在价格上统一加(补贴)或减(收税)一个数,但是购买的人数不变,然后使得政府给出的这个价位获得的利润是所有价位都经过这个变化后中最大的。

实现我们可以用两个数组,一个用来输入,另一个,下标表示价格,数组里的值代表这个下标的价格所对应的人数。

这个问题有两个部分:

1.补全表格(此题最难部分)

题目有一个隐藏条件:在任意两个给定了人数的价格之间如果有没有给定人数的价格,那么中间所有没有给定人数的价格的人数都是“均匀地下降”,就是每两个价格所对应的人数差是一样的。

所以,遇到没有输入人数的价格时,就有三种情况:

  1. 这个价格小于给定人数的最大价格。

  2. 这个价格大于给定人数的最大价格。

  3. 这个价格是不合法的。(即小于成本价或者购买人数是负数)

为了避免计算不合法的价格,我们从成本价往上枚举价格,如果计算出来的人数是负数或 \(0\) 就立刻跳出循环。

思考如何计算第一种情况。假设我们已经枚举到了价格 \(=i\)。

我们需要确定这个价格两端最近的已经确定人数的价格是多少,因为我们是从小到大算,所以价格为 \(i-1\) 时的价格肯定已经算出。至于比它大的,枚举可以找出,在枚举的同时我们可以用一个 \(num\) 变量统计一下这中间价格的数量。

然后我们需要计算它对应的人数。怎么算呢?为了好理解我们把它分成两步:

第一步,算出两两价格之间的差值。

公式:\(d=\dfrac{b_{i-1}-b_R}{num}\),可以根据等差公式得出,也可以自己推(难度不大)。

其中 \(b\) 是上述提及实现方式的那个下标代表价格的数组。

第二步,根据 \(i-1\) 算出 \(i\)。

这个就很简单啦, \(b_i=b_{i-1}+d\) 即可。

然后再看看第二种情况。这个很简单,只需要在前面的基础上减去最后输入的那个数就可以了。

代码实现如下:

int l=a[0].money;
while(1){ //只要没有强制退出就一直循环
if(b[l]){ //这个价格输入中有对应,直接跳过
l++;
continue;
}
if(b[l-1]-p<=0) break; //如果这个价格不合法,退出循环
if(l<Max){ //情况一
int R=l,num=1;
while(!b[R]) R++,num++; //统计数量,找右端点
b[l]=b[l-1]-(b[l-1]-b[R])/num;
}else b[l]=b[l-1]-p; //情况二
l++;
Maxr=max(Maxr,l); //寻找合法价格的最右端点
}
Maxr--; //需要 -1,因为在此之前 l 加了 1

2.计算答案

过了难点我们就可以快乐地模拟了!

枚举补贴/收税的钱数,范围随意,能 A 就行/xyx。

大概思路就是暴力把每一个价位下补贴/收税后的利润做对比,如果政府规定的那个价格是最大的就可以输出。

比较简单(指我错了 \(10^9+7\) 遍,细节比较多 (〃>目<)),看代码理解。

for(int i=0;i<=MAXN-5;i++){
//补贴i元
int maxnum=0; //这个变量是用来统计最大的获利
for(int j=a[0].money;j<=Maxr;j++){
maxnum=max(maxnum,(j+i-a[0].money)*b[j]);
}
if(maxnum==(n+i-a[0].money)*b[n]){ //最大获利地数量等于政府规定地价格,输出结束
printf("%d",i);
return 0;
}
//收税i元
maxnum=0;
for(int j=a[0].money;j<=Maxr;j++){
maxnum=max(maxnum,(j-i-a[0].money)*b[j]);
}
if(maxnum==(n-i-a[0].money)*b[n]){
printf("-%d",i); //注意有负号
return 0;
}
}

最后加上预处理、特判等。

特别注意输入,坑死我辣<(  ̄^ ̄)-+——。

Code

#include<cstdio>
#define max(a,b) (a)>(b)?(a):(b)
const int MAXN=(int)1e5+5;
struct node{int money,num;}a[MAXN];
int Max,Maxr,n,p,tot,b[MAXN];
int main(){
//输入及预处理
scanf("%d %d %d",&n,&a[0].money,&a[0].num);
b[a[0].money]=a[0].num;
while(1){
++tot;
scanf("%d %d",&a[tot].money,&a[tot].num);
if(a[tot].money==-1&&a[tot].num==-1){
--tot;
break;
}
Max=max(Max,a[tot].money);
b[a[tot].money]=a[tot].num;
}
//test
//for(int i=a[0].money;i<=Max;i++) printf("%d %d\n",i,b[i]);
scanf("%d",&p);
//补全条件
int l=a[0].money;
while(1){
if(b[l]){
l++;
continue;
}
if(b[l-1]-p<=0) break;
if(l<Max){
int R=l,num=1;
while(!b[R]) R++,num++;
b[l]=b[l-1]-(b[l-1]-b[R])/num;
}else b[l]=b[l-1]-p;
l++;
Maxr=max(Maxr,l);
}
Maxr--;
//枚举
for(int i=0;i<=MAXN-5;i++){
//补贴i元
int maxnum=0;
for(int j=a[0].money;j<=Maxr;j++){
maxnum=max(maxnum,(j+i-a[0].money)*b[j]);
}
if(maxnum==(n+i-a[0].money)*b[n]){
printf("%d",i);
return 0;
}
//收税i元
maxnum=0;
for(int j=a[0].money;j<=Maxr;j++){
maxnum=max(maxnum,(j-i-a[0].money)*b[j]);
}
if(maxnum==(n-i-a[0].money)*b[n]){
printf("-%d",i);
return 0;
}
}
printf("NO SOLUTION");
return 0;
}

T3 乒乓球

AC at 2021-07-31 14:50:38.

难度:橙

模拟水题,按照一轮一轮枚举。注意一轮结束需要同时满足两个条件,否则不要结束。

这题坑比较多,这里列两个我错过的:

  1. 如果给出的字符串刚刚好到一轮结束,需要在后面再输出一个“0:0”(也不知道为什么);

  2. 如果第一个字符是“E”记得输出两个“0:0”。

Code

#include<cstdio>
#include<cmath>
#include<cstring>
#define max(a,b) (a)>(b)?(a):(b)
int len,tot;
char s[25],a[100005];
int main(){
while(scanf("%s",s+1)!=EOF){
len=strlen(s+1);
for(int i=1;i<=len;i++){
if(s[i]==' '||s[i]=='\n') continue;
if(s[i]=='E') goto type1;
a[++tot]=s[i];
}
}
type1:
int w,l;
if(!tot){
printf("0:0\n\n0:0");
return 0;
}
//11
for(int i=1;i<=tot;i++){
w=0,l=0;
while((w<11&&l<11||abs(w-l)<2)&&i<=tot){
w+=(a[i]=='W');
l+=(a[i]=='L');
i++;
}
i--;
if(i==tot){
printf("%d:%d\n",w,l);
if(w==11||l==11) printf("0:0\n");
break;
}else printf("%d:%d\n",w,l);
}
printf("\n");
//21
for(int i=1;i<=tot;i++){
w=0,l=0;
while((w<21&&l<21||abs(w-l)<2)&&i<=tot){
w+=(a[i]=='W');
l+=(a[i]=='L');
i++;
}
i--;
if(i==tot){
printf("%d:%d\n",w,l);
if(w==21||l==21) printf("0:0\n");
break;
}else printf("%d:%d\n",w,l);
}
return 0;
}

T4 不高兴的津津

AC at 2021-07-30 21:25:42.

难度:红

这真的没什么好说的了,模拟即可 ,有手就行。/cy

Code

#include<cstdio>
#define max(a,b) (a)>(b)?(a):(b)
int Max,ans,a,b;
int main(){
for(int i=1;i<=7;i++){
scanf("%d %d",&a,&b);
if(Max<a+b) ans=i;
Max=max(a+b,Max);
}
if(Max<=8) ans=0;
printf("%d",ans);
return 0;
}

T5 花生采摘

AC at 2021-07-31 14:12:53.

难度:橙

为什么我觉得这道题应该算这套题里面比较难的了?

首先注意一个大坑:采花生需要时间!(这个我错了很久)

然后如果您认真读题,就会发现它并不是一个 dp,而是一个不大的模拟( ̄y▽, ̄)╭ 。(因为 mjl 归类的是模拟板块,我想如果这是考场上我八成会犯这个错误)。

首先把所有花生的坐标和

判断是否能摘到

NOIP&CSP PJ 难度刷题记录的更多相关文章

  1. PE刷题记录

    PE刷题记录 PE60 / 20%dif 这道题比较坑爹. 所有可以相连的素数可以构成一张图,建出这张图,在其中找它的大小为5的团.注意上界的估算,大概在1W以内.1W内有1229个素数,处理出这些素 ...

  2. leetcode刷题记录--js

    leetcode刷题记录 两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但 ...

  3. Leetcode刷题记录(python3)

    Leetcode刷题记录(python3) 顺序刷题 1~5 ---1.两数之和 ---2.两数相加 ---3. 无重复字符的最长子串 ---4.寻找两个有序数组的中位数 ---5.最长回文子串 6- ...

  4. 刷题记录:[HarekazeCTF2019]encode_and_encode

    目录 刷题记录:[HarekazeCTF2019]encode_and_encode 一.知识点 JSON转义字符绕过 php伪协议 刷题记录:[HarekazeCTF2019]encode_and_ ...

  5. 刷题记录:[De1CTF 2019]Giftbox && Comment

    目录 刷题记录:[De1CTF 2019]Giftbox && Comment 一.知识点 1.sql注入 && totp 2.RCE 3.源码泄露 4.敏感文件读取 ...

  6. 刷题记录:[强网杯 2019]Upload

    目录 刷题记录:[强网杯 2019]Upload 一.知识点 1.源码泄露 2.php反序列化 刷题记录:[强网杯 2019]Upload 题目复现链接:https://buuoj.cn/challe ...

  7. 刷题记录:[XNUCA2019Qualifier]EasyPHP

    目录 刷题记录:[XNUCA2019Qualifier]EasyPHP 解法一 1.error_log结合log_errors自定义错误日志 2.include_path设置包含路径 3.php_va ...

  8. 刷题记录:[DDCTF 2019]homebrew event loop

    目录 刷题记录:[DDCTF 2019]homebrew event loop 知识点 1.逻辑漏洞 2.flask session解密 总结 刷题记录:[DDCTF 2019]homebrew ev ...

  9. 刷题记录:[CISCN2019 东北赛区 Day2 Web3]Point System

    目录 刷题记录:[CISCN2019 东北赛区 Day2 Web3]Point System 知识点 1.padding-oracle attack 2.cbc字节翻转攻击 3.FFMpeg文件读取漏 ...

随机推荐

  1. unity调用安卓方法实现安装apk文件(androidx)

    原文链接:点击打开 unity想要实现安装apk文件需要与安卓通讯,所以需要自己来实现安卓代码. 第一步先要新建一个安卓项目提供给unity来使用,我这里使用的工具是android studio4.1 ...

  2. unity 通过JsonUtility实现json数据的本地保存和读取

    本文主要讲解json数据在本地的保存和读取,使用的是unity5之后提供的JsonUtility工具. 一.关于json数据的保存 在实际开发中,有时候可能涉及到大量数据保存到本地,以便于下次客户端的 ...

  3. Vue(13)子组件与父组件超详细解析

    父组件和子组件 我们经常分不清什么是父组件,什么是子组件.现在来简单总结下:我们将某段代码封装成一个组件,而这个组件又在另一个组件中引入,而引入该封装的组件的文件叫做父组件,被引入的组件叫做子组件.具 ...

  4. 关于VIM的迁移

    将Gvim7.3从我笔记本拷到公司的电脑上面时, 这问题留了好久没有去解决.语法高亮无效不管我怎么设置 syntax enable,还是遇到这个问题. 后来在偶然的情况下,将我笔记本上面的文件在拷一份 ...

  5. 8、SpringBoot整合之SpringBoot整合MongoDB

    SpringBoot整合MongoDB 一.创建项目,选择依赖 仅选择Spring Web.Spring Data MongoDB即可 二.引入相关依赖(非必要) 这里只是为了实体类的创建方便而引入l ...

  6. docker安装和配置nginx

    配置nginx docker配置nginx 本机ip是192.168.0.200 docker pull nginx 配置nginx主机 vi /root/docker/nginx/nginx01.c ...

  7. pip 下载时出现问题TypeError: unsupported operand type(s) for -=: 'Retry' and 'int'

    我这里解决就是更新下载源,马德,中科的源居然不够快,我就只能换源了,一换就成功了 1.一次性(临时使用): 可以在使用pip的时候加参数-i https://pypi.tuna.tsinghua.ed ...

  8. swoole实现任务定时自动化调度详解

    开发环境 环境:lnmp下进行试验 问题描述 这几天做银行对帐接口时,踩了一个坑,具体需求大致描述一下. 银行每天凌晨后,会开始准备昨天的交易流水数据,需要我们这边请求拿到. 因为他们给的是一个bas ...

  9. Rust 与 Golang - 何时使用它们?

    [转自 Fizer Khan的<Rust Vs Golang - When to use them?>(翻译)] 在过去的十年中,Rust 和 Go 两种新的编程语言主要为企业开发而开发和 ...

  10. 单点登录(SSO)实现原理(转)

    简介 单点登录是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统的保护资源,若用户在某个应用系统中进行注销登录,所有的应用系统都不能再直接访问保护资源,像一些知名的大型网站,如:淘 ...