总题单
本部分总题单如下
【腾讯文档】副本-CSP-JS+NOI 题单 (未完待续)
https://docs.qq.com/sheet/DSmJuVXR4RUNVWWhW?tab=BB08J2
栈篇题单

P1165 日志分析
https://www.luogu.com.cn/problem/P1165
题目描述
M 海运公司最近要对旗下仓库的货物进出情况进行统计。目前他们所拥有的唯一记录就是一个记录集装箱进出情况的日志。该日志记录了两类操作:第一类操作为集装箱入库操作,以及该次入库的集装箱重量;第二类操作为集装箱的出库操作。这些记录都严格按时间顺序排列。集装箱入库和出库的规则为先进后出,即每次出库操作出库的集装箱为当前在仓库里所有集装箱中最晚入库的集装箱。
出于分析目的,分析人员在日志中随机插入了若干第三类操作――查询操作。分析日志时,每遇到一次查询操作,都要报告出当前仓库中最大集装箱的重量。
输入格式
包含 N + 1 N+1 N+1 行:
第一行为一个正整数 N N N ,对应于日志内所含操作的总数。
接下来的 N N N 行,分别属于以下三种格式之一:
- 格式 1:
0 X
,表示一次集装箱入库操作,正整数 X X X 表示该次入库的集装箱的重量。 - 格式 2:
1
,表示一次集装箱出库操作,(就当时而言)最后入库的集装箱出库。 - 格式 3:
2
,表示一次查询操作,要求分析程序输出当前仓库内最大集装箱的重量。
当仓库为空时你应该忽略出库操作,当仓库为空查询时你应该输出 0 0 0 。
输出格式
输出行数等于日志中查询操作的次数。每行为一个整数,表示查询结果。
输入输出样例 #1
输入 #1
txt
13
0 1
0 2
2
0 4
0 2
2
1
2
1
1
2
1
2
输出 #1
txt
2
4
4
1
0
说明/提示
数据范围及约定
- 对于 20 % 20\% 20% 的数据,有 N ≤ 10 N \le 10 N≤10 ;
- 对于 40 % 40\% 40% 的数据,有 N ≤ 1000 N \le 1000 N≤1000 ;
- 对于 100 % 100\% 100% 的数据,有 1 ≤ N ≤ 200000 1 \le N \le 200000 1≤N≤200000 , 1 ≤ X ≤ 1 0 8 1 \le X \le 10^8 1≤X≤108 。
代码1
先入后出,很经典的栈操作题。由于数据量大,难度在最大值的求法,暴力搜是不行的。需要引入辅助栈。 辅助栈专门记录栈当前的最大值。如果push值大于辅助栈的头元素,则辅助栈中压入要push的值,否则重复压入辅助栈的头元素。比如: A栈为主栈,输入数据依次入栈:1 2 3 5 4; B栈为辅栈,记录对应的最大值:1 2 3 5 5; 弹出时,两栈同时弹出即可。
cpp
#include<bits/stdc++.h>
using namespace std;
stack<int>a; // a为存储集装箱的栈
stack<int>b; // b为存储与a序号一致时的最大重量栈
int n,m,x;
int main()
{
scanf("%d",&n);
while(n--)
{
scanf("%d",&m);
if(m==0) // 入口操作
{
scanf("%d",&x);
a.push(x); // 把重量为x的入库
if(b.empty()||x>b.top()) // 如过b为空或x比b的顶部重
b.push(x);// 把x插入到b中,此时x是最重的集装箱
else b.push(b.top()); // 否则给b中重复插入b的顶部
// 上面的步骤保证了如果a中插入一次,b中也插入一次,同时b中插入的是当前序号的最重数量
}
else if(m==1) // 如果删除 就都删除
{
a.pop(); //
b.pop();
}
else // 查询
{
// 如果b栈空了,输出0 否则输出b的栈顶
if(b.empty()) printf("0\n");
else printf("%d\n",b.top());
}
}
return 0;
}
现场真题注意事项
https://cspoj.com/contest.php?cid=1002Fus5yz4x3EcSJH1Z
注意事项
文件名(程序名和输入输出文件名)必须使用英文小写。(提交必须使用freopen()进行提交)
C/C++ 中函数 main() 的返回值类型必须是 int,程序正常结束时的返回值必须是0。
提交的程序代码文件的放置位置请参考各省的具体要求。
因违反以上三点而出现的错误或问题,申述时一律不予受理。
若无特殊说明,结果的比较方式为全文比较(过滤行末空格及文末回车)。
程序可使用的栈空间内存限制与题目的内存限制一致。
全国统一评测时采用的机器配置为:Inter® Core™ i7-8700K CPU @3.70GHz,内存 32GB。上述时限以此配置为准。
只提供 Linux 格式附加样例文件。
评测在当前最新公布的 NOI Linux 下进行,各语言的编译器版本以此为准
假设输入样例数据存在文件test.in中,输出样例数据存在文件test.out中,
则在CSP、NOI等比赛的代码中,需添加freopen、fclose语句,
内容详见模板代码如下。
cpp
#include <bits/stdc++.h>
#include<cstdio>//必须包含cstdio头文件
#include<iostream>
using namespace std;
int main(){
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
cout<<"Hello NOI"<<endl;
fclose(stdin);
fclose(stdout);
return 0;
}
复制
下面为函数的简介,详细可参见 http://www.cplusplus.com/reference/clibrary/cstdio/freopen.html
函数名:freopen
声明:FILE freopen( const char path, const char mode, FILE stream );
所在文件: stdio.h
参数说明:
path: 文件名,用于存储输入输出的自定义文件名。
mode: 文件打开的模式。和fopen中的模式(如r-只读, w-写)相同。
stream: 一个文件,通常使用标准流文件。
返回值:成功,则返回一个path所指定文件的指针;失败,返回NULL。(一般可以不使用它的返回值)
功能:实现重定向,把预定义的标准流文件定向到由path指定的文件中。标准流文件具体是指stdin、stdout和stderr。其中stdin是标准输入流,默认为键盘;stdout是标准输出流,默认为屏幕;stderr是标准错误流,一般把屏幕设为默认。通过调用freopen,就可以修改标准流文件的默认值,实现重定向。
cpp
#include<iostream>
#include<cstdio>
using namespace std;
int main(){
freopen("7532.in", "r", stdin);
freopen("7532.out", "w", stdout);
//原来的代码保持不变
double a, b, r;
int k;
cin >> a >> b;
k = int(a/b);
r = a - b * k;
printf("%g", r);
//-------------
fclose(stdin);
fclose(stdout);
return 0;
}