对拍是什么?对拍是一种校验程序正确性的方法,通过比较两个程序的同一个测试样例的输出结果,就可以做到判断正确性。
想必各位dalao们都会对拍吧,在oi这种shabi赛制中,对拍就显得尤为重要。
但是,如果你哪天运气不好,遇到了构造题,应该怎么办呢?
其实说的高大上,这个玩意其实不难,营养并不多,比赛的时候动动小聪明其实也能想到
构造题
构造题大多都是让你根据给你的条件,搞出一种符合条件的答案,所以答案可能不唯一。
我们对拍的时候就是不知道答案不唯一的问题,所以在这种情况下,我们可以在比较程序里手写check函数来判断就行了,下面我用一道题来举个例子。
CF743C
题目的意思就是说给你个n,然后要求你构造出一组(x,y,z)满足x1+y1+z1=n2
懒得说解法了,说一说这题怎么对拍吧。
假如我们写了个这个代码想要检测对不对:
1 2 3 4 5 6 7 8 9 10 11 12 13
| #include<bits/stdc++.h> using namespace std; int main() { int n; cin >> n; if (n == 1) { cout << -1; } else { cout << n << ' ' << n + 1 << ' ' << n * (n + 1); } return 0; }
|
我们可以在代码里搞一个随机数据生成器,然后再写一个check判断就ok了。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| #include<bits/stdc++.h> using namespace std; tuple<int, int, int> solve(int n) { if (n == 1) { return {-1, -1, -1}; } else { return {n, n + 1, n * (n + 1)}; } } bool check(int tcc, tuple<int, int, int> a) { if (tcc == 1) { return get<0>(a) == -1; } int ta = get<0>(a); int tb = get<1>(a); int tc = get<2>(a); return (double)1 / (double)ta + (double)1 / (double)tb + (double)1 / (double)tc == (double)2 / (double)tcc; } int main() { srand(time(0)); while (1) { int tc = rand(); if (check(tc, solve(tc))) { cout << "ok!" << '\n'; } else { cout << tc << '\n'; break; } } return 0; }
|
这个代码其实很简单就能看懂,本质上就是不断放进去tc然后判断答案是否合法,碰到了构造题大部分都可以用这个思路来检测。