前言

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

这只是 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. 在vue中下拉框切换事件中改新建表单中的一个值,页面不显示

    事件中改新建表单中的一个值,页面不显示,当另一个对象值发生改变时,这个页面上的值才会显示 由于新建表单是弹窗,在弹出时会重新给每个字段重新赋值,在赋值时没给这个字段赋值(常见新加功能时,加了一个字段, ...

  2. Mysql Limit 调优

    建表与插入数据 SQL对比 基本数据 创建表 CREATE TABLE student ( id int(10) NOT NULL AUTO_INCREMENT, name varchar(25) D ...

  3. iOS 针对txt文档进行解码

    如我上一篇文章记录,我加了打开其他APPtxt文件的小功能,紧接着碰到新问题了,我在测试过程中发现用户上传的TXT编码格式很多不单单是utf-8和gb2312,针对TXT文档进行解码,我一共经历过两个 ...

  4. Sqlite3:Sqlite3命令行Linux操作

    1.查看sqlite版本 [istester@ietester.com idoxu]$ sqlite3 -version 2.进入sqlite后台操作 指定一个完整文件的路径名,打开或者创建数据库(文 ...

  5. SpringMVC(4)数据绑定-1

    在SpringMVC(3)URL请求到Action的映射规则我们介绍了请求是如何映射到一个action上的,下一步当然是如何获取到请求中的数据,这就引出了本篇所要讲的内容-数据绑定. 首先看一下都有哪 ...

  6. vim 知识点小结

    vim用法可以学习:vim用法 Vim修改tab为4个空格 vi /etc/vim/vimrc 添加:set ts=4 vim中翻页的快捷键:向上翻页 ctrl+b,向下翻页 ctrl+f vim替换 ...

  7. Swoole实现毫秒级定时任务

    项目开发中,如果有定时任务的业务要求,我们会使用linux的crontab来解决,但是它的最小粒度是分钟级别,如果要求粒度是秒级别的,甚至毫秒级别的,crontab就无法满足,值得庆幸的是swoole ...

  8. mac 下彻底卸载node和npm

    以下链接可供参考: https://segmentfault.com/a/1190000007445643 https://www.cnblogs.com/ChenGuangW/p/11398367. ...

  9. 浅谈C++11中的多线程(一)

    摘要 本篇文章围绕以下几个问题展开: 进程和线程的区别 何为并发?C++中如何解决并发问题?C++中多线程的基本操作 同步互斥原理以及多进程和多线程中实现同步互斥的两种方法 Qt中的多线程应用 c++ ...

  10. B 站崩了,受害程序员聊聊

    非吃瓜,B 站事件始末分析 + 防治技术分享 大家好,我是鱼皮,昨天小破站崩了的事情相信很多朋友都听说了. 这要是搁以前,不爱吃瓜的我根本不会去关注这种事,崩了就崩了呗,反正天塌下来有程序员大佬们扛着 ...