[语言月赛202306] std::cerr

Luogu
IDLGB3785
Time1000ms
Memory128MB
DifficultyP2
2023Special JudgeO2优化语言月赛
以下给出两个问题的题目描述: #### 问题 1 给出整数 $a, b,c$,求 $\left\lceil\dfrac {a}{b - c} \right\rceil$ 的值,其中 $\left\lceil x \right\rceil$ 表示不小于 $x$ 的最小整数。 #### 问题 2 `std::cerr` 是一个输出到**标准错误流**的输出工具。如果你运行如下程序: ```cpp #include <iostream> int main() { std::cerr << "Hello Luogu!" << std::endl; } ``` 你会发现有 $\texttt{Hello Luogu!}$ 被打印在了命令行 /cmd 中;但是,如果你在 `main` 函数开头加入 `freopen("text.txt", "w", stdout)`,再运行这个程序,然后打开 `text.txt`,会发现文件是空的,而 $\texttt{Hello Luogu!}$ 仍然被打印到了命令行 /cmd 中。 由此,`std::cerr` 在算法竞赛中有了一个重要应用:使用 `std::cerr` 输出中间变量,变量会被打印到屏幕上,但却不会被打印到输出文件/标准输出中。同时,`std::cerr` 有**刷新缓冲区**的作用。以往关闭流同步代码一旦产生 Runtime Error,在这之前被打印到 stdout 的内容如果仍在缓冲区,则不会被输出,而使用 `std::cerr` 则不会有这个问题,因为每次完成输出后都会将缓冲区内容直接刷新到标准错误流中。 例如,你可以尝试在本地运行如下代码: ```cpp #include <iostream> int main() { std::ios::sync_with_stdio(false); std::cout << "Hello Luogu!\n"; int x = *((int*)0); } ``` 对于大多数机器,屏幕上什么都不会打印,应用程序就会异常终止,这种情况是不利于调试的,因为无法二分出导致程序终止语句是哪一条。但是,如果你将上文中的 `std::cout` 换成 `std::cerr` 再尝试运行这一程序,就会发现在程序异常终止前,$\texttt{Hello Luogu!}$ 被打印到了屏幕上。需要注意的是,刷新缓冲区是一件速度很慢的事情,如果刷新次数太多,会导致程序超时。 在刚结束的 ICPC 山东省赛中,扶苏试图使用 `std::cerr` 来完成对 K 题的调试,但是在四小时 59 分提交的代码中,扶苏本已经写出了正确的代码,但却忘记了删除 `std::cerr` 的调试语句,虽然这**不会**导致她向选手输出中输出额外信息,但因为刷新缓冲区次数过多,她本次提交被判定为 `TIME LIMIT`,与省赛冠军失之交臂。 ![](https://picx.zhimg.com/v2-e4ea329a8ca6efbe71a5b97c2e6aeb25_r.jpg?source=1940ef5c) ![](https://pica.zhimg.com/v2-b47fa9073fc1dfa67ee33e7920ca6100_r.jpg?source=1940ef5c) (计算可得,如果第四发 K 题的 attempt 通过,『四小时下班』将以 $8$ 分钟罚时的优势绝杀夺冠) 因此,对于一个字符串,她觉得如果这个字符串含有 `std::cerr` 作为子串,则她觉得这个字符串『不太行』,否则她觉得这个字符串『非常行』。 给定 $T$ 个字符串,请你判断它们是不是『不太行』。 ## Input #### 问题 1 输入只有一行三个整数,依次表示 $a$,$b$,$c$。 #### 问题 2 第一行是一个整数,表示输入字符串个数 $T$。 接下来 $T$ 行,每行一个字符串,表示需要你判断的字符串。 在问题 $2$ 中,输入**不能有**行末空格。但可以有文末回车。 ## Output #### 问题 1 输出一行一个整数表示答案。 #### 问题 2 输出一行一个整数,表示『不太行』的字符串数量。 [samples] ## Background 这是一道 **hack 题**。在本题目中,你将得到两个问题和两个解决对应问题的代码,但是给出的代码不能对于某些输入给出正确的输出。不能给出正确的输出的情况包括: 1. 输出错误的结果。 2. 运行超时。 3. 产生一些运行时未定义行为。目前技术可检测的未定义行为仅包括数组越界。 对于这一问题,你需要提交一份符合要求的输入数据,使得给定的代码不能给出正确的输出。你可以直接使用『提交答案』功能,也可以提交一份以任何语言写成的数据生成器。 每道题占 $50$ 分,本题共 $100$ 分。 --- **提示:如果你使用提交答案功能,请在提交其他题目时记得将语言改回你所使用的语言。** ## Note ### 样例组与实际输入的说明 两个样例分别对应两个问题的样例输入输出。 如果你直接采用『提交答案』的方式,请分别将两个输入数据命名为 `1.in`、`2.in`,并打成 zip 压缩包进行提交; 如果你采用提交数据生成器的方式,你的生成器可以从标准输入读入一个整数 $x$,满足 $1 \leq x \leq 2$,表示该测试点对应的问题编号,然后**输出对应的输入数据**。 显然,你的程序不应该读入『输入格式』里提到的任何内容(而应该构造它们),也不应该输出『样例输出』里提到的任何内容(而是只输出你构造的输入数据)。你不应该使用样例测试你的程序,这只是对两个问题的样例说明。 ### 数据规模要求 你给出的数据必须满足如下要求: 1. 完全符合『输入格式』的规定,不能有多余的输入,但是可以有文末回车,问题 $1$ 可以有行末空格。 2. 对于问题 $1$,$1 \leq a, b, c \leq 100$,$b \neq c$。 3. 对于问题 $2$,$1 \leq T \leq 10^6$,输入字符串的总长度不超过 $2 \times 10^6$,输入的任何字符串不能为空串,且只能含有可见字符(ASCII 值在 $33$ 到 $126$ 之间,空格**不算**可见字符)。 ### 目标代码 你需要 hack 如下的代码: #### 问题 1 ```cpp #include <iostream> using namespace std; int main() { int a, b, c; cin >> a >> b >> c; int d = b - c; cout << ((a + d - 1) / d) << endl; } ``` #### 问题 2 ```cpp #include <iostream> int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int T; std::string s; int ans = 0, cur = 0; for (std::cin >> T; T; --T) { std::cin >> s; ++cur; if (s.find("std::cerr") != std::string::npos) { std::cerr << cur << '\n'; ++ans; } } std::cout << ans << std::endl; } ``` 目标代码的编译选项为 `-std=c++14 -fno-asm -O2`。编译器为洛谷提供的 g++。你可以在『在线 IDE』中选择 C++14 语言来获得完全相同的编译环境。 #### 数据判定 你给出的数据必须完全符合『数据规模要求』,否则将得到 Unaccepted 的结果。 #### 超时判定 程序每执行若干条指令,我们会检测一遍程序的运行时间。我们保证两次检测之间的指令条数是一个输入规模无关的量,也即每执行 $O(1)$ 条指令会进行一次检测。且两次检测之间的指令条数不会太多,一般不超过 $100$ 条 C++ 语句。 如果程序的运行时间超过 $500 \text{ms}$,则判定为程序运行超时,返回 accepted 结果。 #### 结果错误判定 如果程序在规定的时间内结束且给出了一个输出,我们会比较这个输出和**完全正确的输出**,如果二者不同,则判定为 hack 成功,返回 accepted 结果。 #### 未定义行为判定 我们会在每次**显式**的调用数组元素前判断数组下标是否超过数组范围,如果超过,则判定为 hack 成功,返回 accepted 结果。 这就是说,如果你希望通过未定义行为进行 hack,只能对显式的调用数组元素的行为进行 hack。 ### 样例程序 这是一份可以帮你理解你需要输出的内容的样例程序,**但它不能给出正确的 hack 数据**。直接提交此程序不会得分。 ```cpp #include <iostream> using namespace std; int main() { int taskId; cin >> taskId; if (taskId == 1) { cout << "" <<endl; } else if (taskId == 2) { cout << "" << endl; } else { // 这个 else 不会被执行 cout << "Stupid Fusu!" << endl; } } ``` 如果你使用『提交答案』功能,请务必保证打开压缩包后能且仅能**直接**看到两个 `.in` 文件。这就是说,文件结构必须是: ```plain ans.zip |---1.in |---2.in ``` 两个文件不应该被额外的文件夹包含,即文件结构不能是: ```plain ans.zip |---ans(folder) |---1.in |---2.in ``` ### 关于评测信息的说明 如果 hack 成功,对应测试点的信息为 accepted。如果返回其他信息,说明程序本身有误。 例如,如果返回 TLE,不代表成功的将对应程序 hack 至超时,而是表示数据生成器本身运行超时,测试点不得分。 特别的,返回 UKE 结果可能是数据不合法(有多余内容、缺少内容或数据范围不符合要求)。
Samples
Input #1
9 8 5
Output #1
3
Input #2
3
std::cerr
std::cerr<<"HelloLuogu!";
std::cout<<"HelloLuogu!";
Output #2
2
API Response (JSON)
{
  "problem": {
    "name": "[语言月赛202306] std::cerr",
    "description": {
      "content": "以下给出两个问题的题目描述: #### 问题 1 给出整数 $a, b,c$,求 $\\left\\lceil\\dfrac {a}{b - c} \\right\\rceil$ 的值,其中 $\\left\\lceil x \\right\\rceil$ 表示不小于 $x$ 的最小整数。 #### 问题 2 `std::cerr` 是一个输出到**标准错误流**的输出工具。如果你运行如下程序: ```c",
      "description_type": "Markdown"
    },
    "platform": "Luogu",
    "limit": {
      "time_limit": 1000,
      "memory_limit": 131072
    },
    "difficulty": {
      "LuoguStyle": "P2"
    },
    "is_remote": true,
    "is_sync": true,
    "sync_url": null,
    "sign": "LGB3785"
  },
  "statements": [
    {
      "statement_type": "Markdown",
      "content": "以下给出两个问题的题目描述:\n\n#### 问题 1\n\n给出整数 $a, b,c$,求 $\\left\\lceil\\dfrac {a}{b - c} \\right\\rceil$ 的值,其中 $\\left\\lceil x \\right\\rceil$ 表示不小于 $x$ 的最小整数。\n\n#### 问题 2\n\n`std::cerr` 是一个输出到**标准错误流**的输出工具。如果你运行如下程序:\n\n```c...",
      "is_translate": false,
      "language": "English"
    }
  ]
}
Full JSON Raw Segments