OI赛制对拍代码(蓝桥杯对拍代码)
视频讲解链接:Codeforces讲解他来了?蓝桥杯备战技巧之对拍器_哔哩哔哩_bilibili
先写题目的一个优化代码,当不知道是否正确的时候,可以写一个暴力代码(必须保证正确),否则两个代码比较毫无意义,之后再写一个构造随机数据的代码。最后将构造的随机数据传入优化代码和暴力代码中运行,看结果是否正确。
以01背包为例:优化代码是DP,暴力代码用DFS实现:
优化代码DP:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int n, m;
int f[N];
int main()
{
///输入重定向,将input.txt的内容以读的方式写给 标准输入流(stdin)
freopen("input.txt", "r", stdin);
///输出重定向,将stdout的内容以写的方式写给 文件 DP.txt ,此时会创建一个 DP.txt 文件
freopen("DP.txt", "w", stdout);
///这相当于读input.txt文件的内容到m,n中
cin >> n >> m;
for (int i = 1; i <= n; i ++ )
{
int v, w;
cin >> v >> w;
for (int j = m; j >= v; j -- )
f[j] = max(f[j], f[j - v] + w);
}
///将f[m] 的内容写到 DP.txt文件中
cout << f[m] << endl;
return 0;
}
暴力代码DFS:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int n, m;
int v[N], w[N];
int ans;
void dfs(int u, int sum, int value)
{
if (u == n) ans = max(ans, value);
else
{
dfs(u + 1, sum, value);
if (sum + v[u] <= m)
dfs(u + 1, sum + v[u], value + w[u]);
}
}
int main()
{
///输入重定向,将input.txt的内容以读的方式写给 标准输入流(stdin)
freopen("input.txt", "r", stdin);
///输出重定向,将stdout的内容以写的方式写给 文件 DFS.txt ,此时会创建一个 DFS.txt 文件
freopen("DFS.txt", "w", stdout);
///这相当于读input.txt文件的内容到m,n中
cin >> n >> m;
for (int i = 0; i < n; i ++ ) cin >> v[i] >> w[i];
dfs(0, 0, 0);
///将ans 的内容写到 DFS.txt文件中
cout << ans << endl;
return 0;
}
构造随机生成数据代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <fstream>
#include <ctime>
using namespace std;
const int mod = 50;
void create_data()
{
///创建一个输入流对象,并且新建一个input.txt文件(如果没有的话),
///存在则覆盖,记得后缀加.txt,表示文本文件,别只写input;
ofstream fout("input.txt");
int n = (rand() % mod + mod ) % mod;
int m = (rand() % mod + mod ) % mod;
///fout相当于cout,他将得到的n,m值写入input.txt文件中
fout << n << ' ' << m << endl;
for(int i=0; i<n; ++i)
{
int v = (rand() % mod + mod ) % mod;
int w = (rand() % mod + mod ) % mod;
fout << v << ' ' << w << endl;
}
fout.close(); ///关闭文件,自动保存文件
}
bool work()
{
create_data(); ///生成随机数据
system("DP.exe"); ///执行可执行文件DP
system("DFS.exe"); ///执行可执行文件DFS
return system("fc DP.txt DFS.txt");
///system("fc 文件一 文件二"); 注意中间不能加逗号隔开,如果文件
///相同返回0,不相同返回1
}
int main()
{
srand(time(0));
for (int i = 0; i < 100; i ++ )
{
if(work()) break;
}
return 0;
}
注意,这三个代码要放在同一个文件中,可以在编译器新建一个CPP文件来写随机生成数据代码,然后在此文件下新建两个空文件,用来写DP和DFS,然后保存在该文件夹下。不能在外面新建两个CPP文件,否则执行 system("DP.exe")会出错;
关于如何将输入输出重定向到控制台,也就是我们在IDE上看到的黑框框,这是windows下的操作,在Linux下似乎是不同的命令:
freopen("CON", "r", stdin);
freopen("CON", "w", stdout);
在同一个文件下要新建三个cpp文件,似乎有点麻烦,因此我们可以把DP代码和DFS代码写成两个函数,然后将数据保存到vector中,我在之前也想把结果保存到文件里,然后用文件来进行比较,但是似乎行不通,emm,不知道哪儿有问题。下面给出问题代码:
可以不看:
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
const int mod = 100;
const int N = 1e5+10;
int f[N], v[N], w[N];
int n, m;
int ans = 0;
vector<int> vec1, vec2;
void create_data()
{
ofstream fout("input.txt");
int n = (rand() % mod + mod ) % mod;
int m = (rand() % mod + mod ) % mod;
fout << n << ' ' << m << endl;
for(int i=0; i<n; ++i)
{
int v = (rand() % mod + mod ) % mod;
int w = (rand() % mod + mod ) % mod;
fout << v << ' ' << w << endl;
}
fout.close();
}
void DP()
{
fill(f,f + N, 0);
///输入重定向,将input.txt的内容以读的方式写给 标准输入流(stdin)
freopen("input.txt", "r", stdin);
///输出重定向,将stdout的内容以写的方式写给 文件 DP.txt ,此时会创建一个 DP.txt 文件
freopen("DP.txt", "w", stdout);
///这相当于读input.txt文件的内容到m,n中
cin >> n >> m;
for (int i = 1; i <= n; i ++ )
{
int v, w;
cin >> v >> w;
for (int j = m; j >= v; j -- )
f[j] = max(f[j], f[j - v] + w);
}
///将f[m] 的内容写到 DP.txt文件中
// vec1.push_back(f[m]);
cout << f[m] << endl;
fclose(stdout);
fclose(stdin);
}
void dfs(int u, int sum, int value)
{
if (u == n) ans = max(ans, value);
else
{
dfs(u + 1, sum, value);
if (sum + v[u] <= m)
dfs(u + 1, sum + v[u], value + w[u]);
}
}
void DFS()
{
ans = 0;
///文件重定向,将input.txt的内容以读的方式写给 标准输入流(stdin)
freopen("input.txt", "r", stdin);
///文件重定向,将stdout的内容以写的方式写给 文件 DFS.txt ,此时会创建一个 DFS.txt 文件
freopen("DFS.txt", "w", stdout);
///这相当于读input.txt文件的内容到m,n中
cin >> n >> m;
for (int i = 0; i < n; i ++ ) cin >> v[i] >> w[i];
dfs(0, 0, 0);
///将ans 的内容写到 DFS.txt文件中
//vec2.push_back(ans);
cout << ans << endl;
fclose(stdout);
fclose(stdin);
}
void deal()
{
int n, m;
int f[100];
freopen("input.txt", "r", stdin);
cin >> n >> m;
for(int i=0; i<n; ++i)
cin >> f[i];
cout << n << ' ' << m << endl;
for(int i=0; i<n; ++i)
cout << f[i] << ' ';
puts("");
fclose(stdin);
}
bool work()
{
create_data();
deal(); ///所有的deal函数都是测试代码
DP();
deal();
DFS();
freopen("CON", "r", stdin);
freopen("CON", "w", stdout);
///只会输出“error”,奇怪,搞不懂
cout << "made" << endl;
puts("error");
// deal();
// freopen("CON", "r", stdin);
// freopen("CON", "w", stdout);
puts("YES");
return system("fc DP.txt DFS.txt");
// return vec1 == vec2;
}
int main()
{
for(int i=0; i<3; ++i)
{
printf("iterator: %d\n", i);
if(!work()) ;
break;
}
return 0;
}
最后我们再来换个方式,以vector来存储输出数据,因为vector也可以直接比较,相等返回true,否则返回false,也挺方便的:
代码:
/// 2) 以vector来存储输出数据
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
const int mod = 100;
const int N = 1e5+10;
int f[N], v[N], w[N];
int n, m;
int ans = 0;
vector<int> vec1, vec2;
void create_data()
{
ofstream fout("input.txt");
int n = (rand() % mod + mod ) % mod;
int m = (rand() % mod + mod ) % mod;
fout << n << ' ' << m << endl;
for(int i=0; i<n; ++i)
{
int v = (rand() % mod + mod ) % mod;
int w = (rand() % mod + mod ) % mod;
fout << v << ' ' << w << endl;
}
fout.close();
}
void DP()
{
fill(f,f + N, 0);
///输入重定向,将input.txt的内容以读的方式写给 标准输入流(stdin)
freopen("input.txt", "r", stdin);
cin >> n >> m;
for (int i = 1; i <= n; i ++ )
{
int v, w;
cin >> v >> w;
for (int j = m; j >= v; j -- )
f[j] = max(f[j], f[j - v] + w);
}
vec1.push_back(f[m]);
fclose(stdin);
}
void dfs(int u, int sum, int value)
{
if (u == n) ans = max(ans, value);
else
{
dfs(u + 1, sum, value);
if (sum + v[u] <= m)
dfs(u + 1, sum + v[u], value + w[u]);
}
}
void DFS()
{
ans = 0;
///文件重定向,将input.txt的内容以读的方式写给 标准输入流(stdin)
freopen("input.txt", "r", stdin);
cin >> n >> m;
for (int i = 0; i < n; i ++ ) cin >> v[i] >> w[i];
dfs(0, 0, 0);
vec2.push_back(ans + 1);
fclose(stdin);
}
void deal()
{
int n, m;
int f[100];
freopen("input.txt", "r", stdin);
cin >> n >> m;
for(int i=0; i<n; ++i)
cin >> f[i];
cout << n << ' ' << m << endl;
for(int i=0; i<n; ++i)
cout << f[i] << ' ';
puts("");
}
bool work()
{
create_data();
DP();
DFS();
return vec1 == vec2;
}
int main()
{
bool flag = true;
for(int i=0; i<5; ++i)
{
vec1.erase(vec1.begin(), vec1.end());
vec2.erase(vec2.begin(), vec2.end());
printf("iterator: %d\n", i);
if(!work())
{
flag = false;
break;
}
///以下代码可以不要
/*
for(auto ele : vec1)
cout << ele << ' ';
puts("");
for(ele : vec2)
cout << ele << ' ';
puts("");
*/
}
if(!flag)
{
puts("输入:");
deal();
puts("错误输出数据:");
for(auto ele : vec1)
cout << ele << ' ';
puts("");
for(ele : vec2)
cout << ele << ' ';
puts("");
}
return 0;
}