0%

刷题小技巧

文件IO

在刷题测试程序时,为了避免每次都手工输入,我们可以把输入数据保存在文件中;为了避免输出太长,我们将输出也写入文件中,方便与标准答案文件进行比较。
文件使用一般有两种方法:输入输出重定向, fopen。

  • 重定向
    这种方法比较简单,只要在main()函数的开始加上如下代码, 就可以将标准I/O(键盘输入、屏幕输出)转为读写文件:
    1
    2
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);

万一比赛要求标准I/O,而你还想用文件操作来测试代码时,提交时切记删除上述重定向代码。为了避免忘记这茬,可以如下处理:

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#define LOCAL
int main(int argc, char *argv[]) {
#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
// your code here

return 0;
}

这样本机测试时可以使用重定向;如果要求标准I/O,提交时只需删掉#define LOCAL即可。

  • fopen

如果比赛要求使用文件读写,但禁止重定向方式,这时可以使用fopen方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>

int main(int argc, char *argv[]) {
FILE *fin, *fout;
fin = fopen("input.txt", "rb");
fout = fopen("output.txt", "wb");

int a;
// 把scanf改为fscanf, 把printf改为fprintf
fscanf(fin, "%d", &a);
fprintf(fout, "%d", a);
// your code here

fclose(fin);
fclose(fout);
return 0;
}

这时候,如果需要标准I/O,只需要:

1
2
fin = stdin;
fout = stdout;

最后,简单说下windows下的文件比较. 进入cmd:

1
2
fc 1.txt 2.txt  # 两个文件在同一目录
fc "c:\1.txt" "d:\2.txt" # 两个文件不在同一目录

可以使用fc /?查看fc命令的一些参数: 在这里插入图片描述

对拍

对拍是说碰见一道题, 想了个解sol但不知道对不对, 但是呢暴力解bf时间复杂度又太高, 所以希望用随机数据根据bf的正确解验证sol.

除了solbf, 还需要random生成随机数据以及pai来对比结果.

random

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// [0, m - 1]
int random(int m) {
return (long long)rand() * rand() % m;
}

int main() {
srand((unsigned)time(0));
freopen("D:\\FILE\\mycode\\cpp_bishi\\data.in", "w", stdout);

int n = random(100) + 5; // 点的数目
int m = 1000000000; // 取值范围

vector<int> a(n);
printf("%d\n", n);
for (int i = 0; i < n; ++i) {
a[i] = random(m); // 数字取值范围[0, m - 1]
// a[i] = random(2 * m + 1) - m; // [-m, m]
printf("%d", a[i]);
if (i < n - 1) {
printf(" ");
}
}

int n1 = random(1000) + 1, n2 = random(1000) + 1;
vector<vector<int>> b(n1, vector<int>(n2, 0));
printf("%d %d\n", n1, n2);
for (int i = 0; i < n1; ++i) {
for (int j = 0; j < n2; ++j) {
b[i][j] = random(m);
printf("%d", b[i][j]);
if (j < n2 - 1) {
printf(" ");
}
}
printf("\n");
}
}

sol

1
2
3
4
5
int main(int argc, char *argv[]) {
// freopen("D:\\FILE\\mycode\\cpp_bishi\\data.in", "r", stdin);
// freopen("D:\\FILE\\mycode\\cpp_bishi\\data.out", "w", stdout);
return 0;
}

bf

1
2
3
4
int main(int argc, char *argv[]) {
freopen("D:\\FILE\\mycode\\cpp_bishi\\data.in", "r", stdin);
freopen("D:\\FILE\\mycode\\cpp_bishi\\data.ans", "w", stdout);
}

pai

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main() {
for (int T = 1; T <= 100; T++) {
system("D:\\FILE\\mycode\\cpp_bishi\\random.exe");
double st = clock();
system("D:\\FILE\\mycode\\cpp_bishi\\sol.exe");
double ed = clock();
system("D:\\FILE\\mycode\\cpp_bishi\\bf.exe");
if (system("fc D:\\FILE\\mycode\\cpp_bishi\\data.out D:\\FILE\\mycode\\cpp_bishi\\data.ans")) {
puts("wrong ans");
return 0;
}
else {
printf("accepted, id #%d, time %.0lfms\n", T, ed-st);
}
}
}