故事背景:

日常菜菜的一天:

(右下角 QQ 闪动):大佬这里哪里错了啊?(题目代码丢了过来...) 大佬是什么啊嘤嘤嘤

看一眼题,复制代码,打开 vsc Shift + Alt + F 唔.. 这写的啥..

魔改一波,,交上去 AC,看看哪里不一样叭 emmm

看不出来。。好像哪里都一样_(:з」∠)_

于是尝试采用对拍,顺带能水一篇博客 qwq激烈的重复造轮大赛

感谢同学提供代码へ (_ _ へ)

# 咋写对拍

算法竞赛中常用手段~~(然而并不常用)~~,通常是由三个程序构成:

  1. 保证正确性的暴力解 1.exe

  2. 正确性未知,但复杂度更优的解 2.exe

  3. 随机数生成器 3.exe

运行 3.exe ,生成随机输入数据,运行 1.exe2.exe 比较输出结果是否一致,循环下去..

跑一段时间并且没有出现不同的话,基本上可以确定 2.exe 的正确性了。

整个对拍文件夹由以下构成:

<img src = "https://s3.ax1x.com/2020/12/23/ryEz0U.jpg" width = "500px">

其中 3.exe 会生成随机数据到 in.txt 里,由 1.exe2.exe 读取,分别将结果输出到 1.txt2.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。

更新于