NOIP&CSP PJ 难度刷题记录
前言
本来不想写前言的(>人<;)
这只是 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.补全表格(此题最难部分)
题目有一个隐藏条件:在任意两个给定了人数的价格之间如果有没有给定人数的价格,那么中间所有没有给定人数的价格的人数都是“均匀地下降”,就是每两个价格所对应的人数差是一样的。
所以,遇到没有输入人数的价格时,就有三种情况:
这个价格小于给定人数的最大价格。
这个价格大于给定人数的最大价格。
这个价格是不合法的。(即小于成本价或者购买人数是负数)
为了避免计算不合法的价格,我们从成本价往上枚举价格,如果计算出来的人数是负数或 \(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.
难度:橙
模拟水题,按照一轮一轮枚举。注意一轮结束需要同时满足两个条件,否则不要结束。
这题坑比较多,这里列两个我错过的:
如果给出的字符串刚刚好到一轮结束,需要在后面再输出一个“0:0”(也不知道为什么);
如果第一个字符是“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 难度刷题记录的更多相关文章
- PE刷题记录
PE刷题记录 PE60 / 20%dif 这道题比较坑爹. 所有可以相连的素数可以构成一张图,建出这张图,在其中找它的大小为5的团.注意上界的估算,大概在1W以内.1W内有1229个素数,处理出这些素 ...
- leetcode刷题记录--js
leetcode刷题记录 两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但 ...
- Leetcode刷题记录(python3)
Leetcode刷题记录(python3) 顺序刷题 1~5 ---1.两数之和 ---2.两数相加 ---3. 无重复字符的最长子串 ---4.寻找两个有序数组的中位数 ---5.最长回文子串 6- ...
- 刷题记录:[HarekazeCTF2019]encode_and_encode
目录 刷题记录:[HarekazeCTF2019]encode_and_encode 一.知识点 JSON转义字符绕过 php伪协议 刷题记录:[HarekazeCTF2019]encode_and_ ...
- 刷题记录:[De1CTF 2019]Giftbox && Comment
目录 刷题记录:[De1CTF 2019]Giftbox && Comment 一.知识点 1.sql注入 && totp 2.RCE 3.源码泄露 4.敏感文件读取 ...
- 刷题记录:[强网杯 2019]Upload
目录 刷题记录:[强网杯 2019]Upload 一.知识点 1.源码泄露 2.php反序列化 刷题记录:[强网杯 2019]Upload 题目复现链接:https://buuoj.cn/challe ...
- 刷题记录:[XNUCA2019Qualifier]EasyPHP
目录 刷题记录:[XNUCA2019Qualifier]EasyPHP 解法一 1.error_log结合log_errors自定义错误日志 2.include_path设置包含路径 3.php_va ...
- 刷题记录:[DDCTF 2019]homebrew event loop
目录 刷题记录:[DDCTF 2019]homebrew event loop 知识点 1.逻辑漏洞 2.flask session解密 总结 刷题记录:[DDCTF 2019]homebrew ev ...
- 刷题记录:[CISCN2019 东北赛区 Day2 Web3]Point System
目录 刷题记录:[CISCN2019 东北赛区 Day2 Web3]Point System 知识点 1.padding-oracle attack 2.cbc字节翻转攻击 3.FFMpeg文件读取漏 ...
随机推荐
- 安装linux 报错(initramfs) Unable to find a medium containing a live file system
如题,linux 安装报错:(initramfs) Unable to find a medium containing a live file system 我是用UItraISO做的启动盘遇到这个 ...
- React 并发功能体验-前端的并发模式已经到来。
React 是一个开源 JavaScript 库,开发人员使用它来创建基于 Web 和移动的应用程序,并且支持构建交互式用户界面和 UI 组件.React 是由 Facebook 软件工程师 Jord ...
- 快速简单的了解VLAN(VXLAN)和端口链路类型
目录 前言 一.VLAN是什么? 1.优点 2.为什么推出VXLAN 二.VXLAN又是什么? 1.优点 三.创建VLAN 四.介绍端口链路类型 五.Access 1.特性 六.Trunk 1.特性 ...
- react 中的PropTypes与DefaultProps
每个组件都有自己的props参数,这参数是从父组件接收的一些属性.那我们应该如何对参数的类型做校验,如何定义参数的默认值呢? 1.使用PropTypes校验父组件传过来的参数是否合法 import P ...
- excel vba的inputBox函数
Sub test1() Dim h Dim j As Integer j = 0 Dim n1 As Integer '分行单元格在第几列 Dim m1 As Integ ...
- 试着给VuePress添加全局禁止爬取支持,基于vuepress-plugin-robots
背景 有时候,我们有些内部网站希望不被外部抓取,那么我们可以借助vuepress-plugin-robots来生成robots.txt文件,来告诉爬虫不要抓取页面. 安装 npm install vu ...
- PowerMock 支持gRPC的Mock Server实现
PowerMock是一个Mock Server的实现,它同时支持HTTP与gRPC协议接口的Mock,并提供了灵活的插件功能. 这个工具面向于前后端.测试等对有接口Mock需求的开发人员,也可以作为一 ...
- 题解 P5327 [ZJOI2019]语言
P5327 [ZJOI2019]语言 解题思路 暴力 首先讲一下我垃圾的 40pts 的暴力(其他 dalao 都是 60pts 起步): 当然评测机快的话(比如 LOJ 的),可以卡过 3,4 个点 ...
- 使用VS调试时出现 :provider: Named Pipes Provider, error: 40 - 无法打开到 SQL Server 的连接 解决方案
首先检查链接的数据库名称是否正确 其二是看看你的主机名称由没有写对,有些写成 127.0.0.1会出错.我就是将sessionState中的127.0.0.1出错,改为自己的主机名称就OK啦
- Java:Java的重写与重载区分
最明显的区别为:重写只存在于子类与父类中,重载存在于一个类中. 具体区别如下: 一.重写(override) override是重写(覆盖)了一个方法,以实现不同的功能.一般是用于子类在继承父类时,重 ...