给出一个含有N个元素的数列,要求除去元素X后将这个数列输出。
举个例子。若这个数列为:
3 3 2 2 4
除去元素2后数列为:
3 3 4
对于每组测试数据,输出包含两行:
第一行是“Case i:”(其中i代表第几组测试数据);
第二行为删除X后的数列。数列中的每个数用一个空格隔开,注意请不要在最后一个数后面加空格。如果删除X后数列为空,则输出“Empty!”。
每组测试数据之间用一个空行隔开。
本题的需要注意以下几点:
1. 读入依旧是大量的(百万级),相较于lecture (2),此处还多了大量输出(也是百万级),此处建议最好使用scanf和printf。
2. 此处读入的每个数均可能超过int范围,因此需要用long long存放。
3. 所给内存只有4M,若是开一个数组存放这个数列显然是不可取的。我们可以大致估算下内存,一个int变量是4个字节,一个long long变量是8个字节,若开一个100万大小的long long数组,则所需的内存为1000000*8/1024/1024≈7.63MB。内存会超。因为此处所读取的数字没有必要保存,只需边输入边输出就行了,因此开一个long long变量即可。
4. 输入的测试数据之间有一个空行,但其实这是没所谓的,用scanf和cin读入整数的时候,都是自动忽略空白符(包括空格和回车符)的,所以有没有空行对于读入根本没有影响。
5. 如何保证输出的最后一个数后面没有空格?其实这个方法与Case之间加空行一致,通过一个标记,判断是不是第一个输出,如果是第一个则直接输出,否则在输出前加一个空格即可。
6. 关于输入输出格式,如何判断输出格式是否正确?方法很简单,因为系统在评测时,输入与输出是分开的,只需要输出部分格式正确即可。所以在调试时忽略输入,把输出单独拎出来看即可(可在调试窗口上目测,也可通过重定向把输入和输出分开,特别是在输入与输出都有空行,混在一起很难看出的时候,通过把输出重定向到文件上进行格式检测是一个非常有效的方法)。
因此我们可以写出如下代码:
C语言版:
#include<stdio.h>
int main() {
int hasPrinted;
int isFirstCase = 1;
int n, t = 0;
long long a, x;
while (~scanf("%d %lld", &n, &x)) {
hasPrinted = 0;
if (isFirstCase) isFirstCase = 0;
else puts("");
printf("Case %d:\n", ++t);
for (int i = 0; i<n; i++) {
scanf("%lld", &a);
if (a != x) {
if (hasPrinted) printf(" ");
printf("%lld", a);
hasPrinted = 1;
}
}
if (hasPrinted) puts("");
else puts("Empty!");
}
return 0;
}
C++版:
#include<iostream>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(0); // 关闭cin与cout绑定,不加此句会超时
bool hasPrinted;
bool isFirstCase = true;
int n, t = 0;
long long a, x;
while (cin >> n >> x) {
hasPrinted = false;
if (isFirstCase) isFirstCase = false;
else cout << endl;
cout << "Case " << ++t << ":" << endl;
for (int i = 0; i<n; i++) {
cin >> a;
if (a != x) {
if (hasPrinted) cout << " ";
cout << a;
hasPrinted = true;
}
}
if (hasPrinted) cout << endl;
else cout << "Empty!" << endl;
}
return 0;
}