故事背景:
日常菜菜的一天:
(右下角 QQ 闪动):大佬这里哪里错了啊?(题目代码丢了过来...)
大佬是什么啊嘤嘤嘤看一眼题,复制代码,打开 vsc
Shift + Alt + F
唔.. 这写的啥..魔改一波,,交上去 AC,看看哪里不一样叭 emmm
看不出来。。好像哪里都一样_(:з」∠)_
于是尝试采用对拍,
顺带能水一篇博客 qwq,激烈的重复造轮大赛
感谢同学提供代码へ (_ _ へ)
# 咋写对拍
算法竞赛中常用手段~~(然而并不常用)~~,通常是由三个程序构成:
保证正确性的暴力解
1.exe
正确性未知,但复杂度更优的解
2.exe
随机数生成器
3.exe
运行 3.exe
,生成随机输入数据,运行 1.exe
和 2.exe
比较输出结果是否一致,循环下去..
跑一段时间并且没有出现不同的话,基本上可以确定 2.exe
的正确性了。
整个对拍文件夹由以下构成:
<img src = "https://s3.ax1x.com/2020/12/23/ryEz0U.jpg" width = "500px">
其中 3.exe
会生成随机数据到 in.txt
里,由 1.exe
和 2.exe
读取,分别将结果输出到 1.txt
和 2.txt
里。
批处理文件 qwq.bat:
:loop
3.exe
1.exe
2.exe
fc 1.txt 2.txt
if %errorlevel%==0 goto loop
pause
# 实例
Problem:hdoj2031
# 题目大意
给定多组十进制数 N (32 位整数) 和 R (2 <= R <= 16), 把 N 转换成 R 进制输出。
Generator 3.cpp
:
#include <stdio.h> | |
#include <stdlib.h> | |
#include <ctime> | |
#define rep(i,s,t) for(int i=s;i<=t;i++) | |
int main() | |
{ | |
freopen("in.txt", "w", stdout); | |
srand((time(NULL))); | |
int x = (rand()%2) ? 1 : -1; | |
printf("%d %d", rand() % 30 * x, rand() % 16 + 1); // 小范围数据 | |
return 0; | |
} |
Accepted Code 1.cpp
:
拿同学代码魔改的 qwq
#include <stdio.h> | |
#include <string.h> | |
int main() | |
{ | |
freopen("in.txt", "r", stdin); | |
freopen("1.txt", "w", stdout); | |
int n, r, a[10000]; //a 数组倒序记录转换后每位数字 | |
while (scanf("%d %d", &n, &r) != EOF) | |
{ | |
int i, m, sum, flag = 0; | |
if (n < 0) // 转成正数处理,flag 标记符号 | |
{ | |
flag = 1; | |
n = -n; | |
} | |
for (i = 0, m = n, sum = 0; m != 0; i++) | |
{ | |
a[i] = m % r; | |
m = m / r; | |
sum++; //sum 为转换后的位数 (+1) | |
} | |
// 输出部分 | |
if (flag) | |
putchar('-'); | |
for (i = sum - 1; i >= 0; i--) // 倒序输出 | |
{ | |
if (a[i] == 10) | |
printf("%c", 'A'); | |
else if (a[i] == 11) | |
printf("%c", 'B'); | |
else if (a[i] == 12) | |
printf("%c", 'C'); | |
else if (a[i] == 13) | |
printf("%c", 'D'); | |
else if (a[i] == 14) | |
printf("%c", 'E'); | |
else if (a[i] == 15) | |
printf("%c", 'F'); | |
else | |
printf("%d", a[i]); | |
//else if(a[i]==0); | |
//else printf("%d",a[i]); | |
} | |
printf("\n"); | |
} | |
return 0; | |
} |
WA Code 2.cpp
:
基本难以静态查错....
#include <stdio.h> | |
#include <string.h> | |
int main() | |
{ | |
freopen("in.txt", "r", stdin); | |
freopen("2.txt", "w", stdout); | |
int n, r, a[10000]; //a 数组倒序记录转换后每位数字 | |
while (scanf("%d %d", &n, &r) != EOF) | |
{ | |
int i, m, sum; | |
for (i = 0, m = n, sum = 0; m != 0; i++) | |
{ | |
a[i] = m % r; // 蜜汁负数取模,不过好像没事 emmm | |
m = m / r; | |
sum++; //sum 为转换后的位数 (+1) | |
} | |
int flag, j; //flag 标记符号 | |
for (i = sum - 1; i >= 0; i--) // 倒序输出 | |
{ | |
flag = 0; | |
if (i == sum - 1) // 判符号(蜜汁判断方式 qwq), 总之是对的 | |
{ | |
for (j = 0; j < sum; j++) | |
{ | |
if (a[j] < 0) | |
flag++; | |
} | |
if (flag != 0) | |
printf("-"); | |
} | |
// 输出本位 | |
if (a[i] == 10) | |
printf("%c", 'A'); | |
else if (a[i] == 11) | |
printf("%c", 'B'); | |
else if (a[i] == 12) | |
printf("%c", 'C'); | |
else if (a[i] == 13) | |
printf("%c", 'D'); | |
else if (a[i] == 14) | |
printf("%c", 'E'); | |
else if (a[i] == 15) | |
printf("%c", 'F'); | |
else if (a[i] < 0) | |
printf("%d", -a[i]); | |
else if (a[i] == 0); | |
else | |
printf("%d", a[i]); | |
} | |
printf("\n"); | |
} | |
return 0; | |
} |
拿去与正解对拍, 第一次卡住:
Input:
16 16
Correct Output:
10
Wrong Output:
1
看上去好像少输出了一些 0,找找 ,,大概是这里,,注释掉,,
printf("%c", 'F'); | |
else if (a[i] < 0) | |
printf("%d", -a[i]); | |
// else if (a[i] == 0); | |
else | |
printf("%d", a[i]); | |
} |
提交 WA,继续对拍,第二次卡住:
Input:
-29 16
Correct Output:
-1D
Wrong Output:
-113
看上去大概负数处理不太对..(话说为什么不在一开始就记住符号。。。
看最后输出部分:
else if (a[i] < 0) | |
printf("%d", -a[i]); |
好像有了特判的样子,但上边:
if (a[i] == 10) | |
printf("%c", 'A'); | |
else if (a[i] == 11) | |
... |
这堆 if-else 没判啊 qwq
直接在 if (a[i] == 10)
前添加 if (a[i] < 0) a[i] = -a[i];
并注释掉:
/* else if (a[i] < 0) | |
printf("%d", -a[i]); | |
else if (a[i] == 0); */ |
提交 AC。