#B3821. [语言月赛 202308] 小粉兔 Failed System Test

[语言月赛 202308] 小粉兔 Failed System Test

题目背景

小粉兔在某场 CF 中 -154,警示大家不能 FST。

这是一道 hack 题。在本题目中,你将得到两个问题和两个解决对应问题的代码,但是给出的代码不能对于某些输入给出正确的输出。不能给出正确的输出的情况包括:

  1. 输出错误的结果。
  2. 运行超时。
  3. 产生一些运行时未定义行为。目前技术可检测的未定义行为仅包括数组越界。

对于这两个问题,你需要分别提交一份符合要求的输入数据,使得给定的代码不能给出正确的输出。你可以直接使用『提交答案』功能,也可以提交一份以任何语言写成的数据生成器。


提示:如果你使用提交答案功能,请在提交其他题目时记得将语言改回你所使用的语言。

题目描述

以下给出两个问题的题目描述:

问题 1

给定 nn 个元素,标号为 1,2,,n1, 2, \cdots, n,你需要标记其中 kk 个元素。如果两个元素标号相差 11 则称二者相邻。

请计算出「自身未被标记且有至少一个相邻元素被标记」的元素的可能的最小数量可能的最大数量

问题 2

给定一个仅包含小写字母 abc 的字符串,判断这个字符串是否符合以下所有特征:

  1. 字符串中至少有一个 a 字母和一个 b 字母,且所有的 ab 之前。
  2. 如果字符串中有 c,所有的 abc 之前,所有的 bc 之前。
  3. c 的数量等于 a 的数量或 b 的数量。

输入格式

问题 1

输入共一行两个整数 n,kn, k

问题 2

输入共一行一个字符串 SS

输出格式

问题 1

输出共一行两个整数,依次代表可能的最小数量和可能的最大数量。

问题 2

输出共一行一个字符串。如果 SS 符合要求,则输出 YES,否则输出 NO

6 3
1 3
aaabccc

YES

提示

样例组与实际输入的说明

两个样例分别对应两个问题的样例输入输出。

如果你直接采用『提交答案』的方式,请分别将两个输入数据命名为 1.in2.in,并打成 zip 压缩包进行提交;

如果你采用提交数据生成器的方式,你的生成器可以从标准输入读入一个整数 xx,满足 1x21 \leq x \leq 2,表示该测试点对应的问题编号,然后输出对应的输入数据

显然,你的程序不应该读入『输入格式』里提到的任何内容(而应该构造它们),也不应该输出『样例输出』里提到的任何内容(而是只输出你构造的输入数据)。你不应该使用样例测试你的程序,这只是对两个问题的样例说明。

数据规模要求

你给出的数据必须满足如下要求:

  1. 完全符合『输入格式』的规定,不能有多余的输入,但是可以有文末回车。
  2. 对于问题 111n1091 \leq n \leq 10 ^ 90kn0 \leq k \leq n
  3. 对于问题 221S50001 \leq \left | S \right | \leq 5000S\left | S \right | 代表字符串 SS 的长度),SS 中仅包含小写字母 a, b, c

目标代码

你需要 hack 如下的代码:

问题 1

#include <bits/stdc++.h>
using namespace std;
int main() {
    int n, k;
    cin >> n >> k;
	if (k == n || k == 0) {
		cout << "0 0" << endl;
		return 0;
	}
	cout << "1 ";
	if (k * 3 <= n)
        cout << 2 * k << endl;
	else
        cout << n - k << endl;
	return 0;
}

问题 2

#include <bits/stdc++.h>
using namespace std;

char str[5005];
int i, n, A, B, C;

int main() {
	cin >> str;
	n = strlen(str);
	if (str[0] != 'a') {
		cout << "NO" << endl;
		return 0;
	}
	for (i = 0; i < n; ++i) 
        if (str[i] != 'a') break;
	A = i;
	for (; i < n; ++i)
		if (str[i] != 'b') break;
	if (i == n || str[i] != 'c') {
		cout << "NO" << endl;
		return 0;
	}
	B = i - A;
	for (; i < n; ++i)
		if (str[i] != 'c') break;
	if (i != n) {
		cout << "NO" << endl;
		return 0;
	}
	C = n - B - A;
	if (C != A && C != B) 
        cout << "NO" << endl;
	else 
        cout << "YES" << endl;
	return 0;
}

目标代码的编译选项为 -std=c++14 -fno-asm -O2。编译器为洛谷提供的 g++。你可以在『在线 IDE』中选择 C++14 语言来获得完全相同的编译环境。

数据判定

你给出的数据必须完全符合『数据规模要求』,否则将得到 Unaccepted 的结果。

超时判定

程序每执行若干条指令,我们会检测一遍程序的运行时间。我们保证两次检测之间的指令条数是一个输入规模无关的量,也即每执行 O(1)O(1) 条指令会进行一次检测。且两次检测之间的指令条数不会太多,一般不超过 100100 条 C++ 语句。

如果程序的运行时间超过 500ms500 \text{ms},则判定为程序运行超时,返回 accepted 结果。

结果错误判定

如果程序在规定的时间内结束且给出了一个输出,我们会比较这个输出和完全正确的输出,如果二者不同,则判定为 hack 成功,返回 accepted 结果。

未定义行为判定

我们会在每次显式的调用数组元素前判断数组下标是否超过数组范围,如果超过,则判定为 hack 成功,返回 accepted 结果。

这就是说,如果你希望通过未定义行为进行 hack,只能对显式的调用数组元素的行为进行 hack。

样例程序

这是一份可以帮你理解你需要输出的内容的样例程序,但它不能给出正确的 hack 数据。直接提交此程序不会得分。

#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 文件。这就是说,文件结构必须是:

ans.zip
 |---1.in
 |---2.in

两个文件不应该被额外的文件夹包含,即文件结构不能是:

ans.zip
 |---ans(folder)
      |---1.in
      |---2.in

关于评测信息的说明

如果 hack 成功,对应测试点的信息为 accepted。如果返回其他信息,说明程序本身有误。

例如,如果返回 TLE,不代表成功的将对应程序 hack 至超时,而是表示数据生成器本身运行超时,测试点不得分。

特别的,返回 UKE 结果可能是数据不合法(有多余内容、缺少内容或数据范围不符合要求)。