对拍是一种比较使用的工具,他可以对比两个程序的输出结果,当我们写完一个程序时,又不太确定这段代码对不对时,对拍就能派上用场了。

我们拿这个题举例子

【小挑战】丢失的珠子
限制 : 20000 MS   2500 KB
问题描述

何老板有一盒珠子共n颗,编号1到n。他一不小心将盒子打翻,所有珠子都散落在地。他一颗一颗地把珠子捡起来,每捡一颗就记录下当前这颗珠子的编号。捡完以后发现少了两颗,请你快速找出少了哪两颗珠子。

输入格式

第一行,一个整数n
接下来一行,n-2个空格间隔的整数,表示何老板捡起来的珠子的编号。

输出格式

一行,由小到大排列的两个整数,表示丢失的两颗珠子的编号。

样例输入 1

7
4  1  7  2  5 

样例输出 1

3  6

样例输入 2

10 
4 5 8 3 9 7 1 2 

样例输出 2

6 10

提示

对于30%的数据,有n<=1,000
对于100%的数据,有n<=1,000,000


喜欢用 cin 读入的小朋友,在程序主函数开头加上 ios::sync_with_stdio(false); 可以让程序的读入效率大幅提高

/*这个题暴力明显超时,那我们就要考虑数学方法*/
#include <iostream>
#define int long long
using namespace std;	
int n,n2,sum1,sum2,sum3,sum4;
signed main(){
	scanf("%lld",&n);
	sum1=(1+n)*n/2;//所有数的和
	for(int i=1;i<=n-2;i++){
		scanf("%lld",&n2);
		sum2+=n2;//现有数的和
		sum3+=n2*n2;//现有数的平方和
	}
	for(int  i=1;i<=n;i++) sum4+=i*i;//所有数的平方和
	for(int i=1;i<=sum1-sum2;i++){
		int  j=sum1-sum2-i;
		if((i*i+j*j)==(sum4-sum3)){//判断
			printf("%lld %lld",i,j);
			return 0;
		}
	}
	return 0;
}

这个题当你写完这样一段代码时,又不能确定对不对,对拍就派上用场了

首先,我们需要一个随机数程序来模拟数据make

​
#include <bits/stdc++.h>
using namespace std;
int n;
int main()
{
	freopen("make.in","w",stdout);//文件重定向
	ios::sync_with_stdio(0);
	srand(time(NULL));//初始随机种子
	n=rand()%1000000+1;
	int t=rand()%1000000+1;
	int s=rand()%1000000+1;//随机缺少的两个数
	while(s==t)s=rand()%1000000+1;//如果重复就继续随机
	cout<<n<<" ";
	for(int i=1;i<=n;i++)
	{
		if(i!=t&&i!=s)
		{
			cout<<i<<" ";
		}
	}
	return 0;
}

​

我们还需要一个暴力程序baoli

#include <bits/stdc++.h>
using namespace std;
long long n;
bool a[1000010];//桶标记
int main()
{
	freopen("make.in","r",stdin);//从make随机数中调取数据
	freopen("baoli.out","w",stdout);
	ios::sync_with_stdio(0);
	cin>>n;
	for(int i=1;i<=n-2;i++)
	{
		int t;
		cin>>t;
		a[t]=true;
	}
	int cnt=0,i=1;
	while(cnt<2)
	{
		if(a[i]==false)
		{
			cout<<i<<" ";
			cnt++;
		}
		i++;
	}
	return 0;
}

然后只需要在我们的正解的基础上加上文件重定向就可以了

#include <bits/stdc++.h>
using namespace std;
long long n;
long long sum,sum2,sum3,ans1,ans2;
int main()
{
	freopen("make.in","r",stdin);
	freopen("zhengjie.out","w",stdout);
	ios::sync_with_stdio(0);
	cin>>n;
	for(long long i=1;i<=n-2;i++)
	{
		long long t;
		cin>>t;
		sum2+=t;
		sum3+=t*t;
	}
	sum=(n+1)*n/2;
	sum2=sum-sum2;
	sum=n*(n+1)*(2*n+1)/6;
	sum3=sum-sum3;
	for(long long i=1;i<=sum2;i++)
	{
		long long y1,y2;
		y1=sum2-i;
		y2=sum3-i*i;
		if(y1*y1==y2)
		{
			ans1=i;
			ans2=y1;
			break;
		}
	}
	if(ans1>ans2)swap(ans1,ans2);
	cout<<ans1<<" "<<ans2<<" ";
	return 0;
}

 这个时候,最关键的对拍程序来了(我们需要建一个txt文件,再将后缀名改为bat)

​
@echo off	//作用是关闭回显
:loop		//执行循环
make.exe	//调用make,生成随机数据到make.in中
zhengjie.exe	//调用baoli,读入make.in的数据并输出结果到zhengjie.out
baoli.exe	//调用zhengjie,读入make.in的数据并输出结果到baoli.out
fc zhengjie.out baoli.out	//对比zhengjie.out和baoli.out的内容是否一致
if not errorlevel 1 goto loop	//若一致,继续对拍
pause				//不一致,结束对拍,显示出错的地方	
:end

​

这个时候,双击bat程序,如果结果一致,则会一直对拍(建议拍一会没问题就关了,不然电脑容易卡)

 如果出错了,也会显示不一致的地方,真的巨使用

对拍也就到这了

完结撒花!!!

愿我不会退役!!!

愿世界和平!!! 

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐