【c++】对拍(超详细)
·
对拍是一种比较使用的工具,他可以对比两个程序的输出结果,当我们写完一个程序时,又不太确定这段代码对不对时,对拍就能派上用场了。
我们拿这个题举例子
| 【小挑战】丢失的珠子 | |
|
问题描述
何老板有一盒珠子共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程序,如果结果一致,则会一直对拍(建议拍一会没问题就关了,不然电脑容易卡)

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

对拍也就到这了
完结撒花!!!
愿我不会退役!!!
愿世界和平!!!
更多推荐
所有评论(0)