造数据的方法
JHR100330
·
2023-10-15 17:13:05
·
个人记录
#include
#include
using namespace std;
int readint() {
int s = 0, w = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
w = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
s = (s << 1) + (s << 3) + (ch ^ '0');
ch = getchar();
}
return s * w;
}
int r(int a, int b){
return rand() * 1000000007ll % (b - a + 1) + a;
}
long long rll(long long a, long long b){
long long ttt = ((long long)rand() * 13331 % (b - a + 1)) * 1000000007ll % (b - a + 1) + a;
return ttt;
}
long long rl(int len){
long long t = 1;
for(int i = 1; i <= len; i ++) t *= 10;
return rll(t / 10, t);
}
#define ll long long
#define DEV_RND ((int)rand()*RAND_MAX+rand())
#define R(L,R) (DEV_RND%((R)-(L)+1)+(L))
string s1[15], s2[15];
int main() {
srand((signed)time(0));
for(int jj = 1; jj <= 20; jj ++){
char fdsafdsa[105]; sprintf(fdsafdsa, "data\\data%03d.in", jj); freopen(fdsafdsa, "w", stdout);
int n, a = rl(9), b = rl(9);
if(jj <= 5){
n = r(190000, 200000);
cout << n << " " << a << " " << b << endl;
for(int i = 1; i <= n; i ++)
cout << i << " " << i + 1 << endl;
continue;
}
else if(jj <= 10) n = 1000;
else n = 200000;
cout << n << " " << a << " " << b << endl;
for(int i = 2; i <= n; i ++)
cout << r(1, i - 1) << " " << i << endl;
fclose(stdout);
}
string in, out;
for(int i = 1;i <= 20;i ++) {
in.clear();
int j = i;
for(int u = 1; u <= 3; u ++){
char m = j % 10 + '0';
in = m + in;
j /= 10;
}
out = in;
in += ".in";
out += ".out";
string A = "data\\data";
string B = "data\\data";
A = A + in,B = B + out;
in = A,out = B;
string Str="刷题.exe < "+ in +" > "+ out;
system(Str.data());
cerr << "Yes\n";
}
// for(int i = 1; i <= 20; i ++){
// char fdsafdsa1[105];sprintf(fdsafdsa1, "data\\data%03d.in", i); freopen(fdsafdsa1, "r", stdin);
// char fdsafdsa2[105];sprintf(fdsafdsa2, "data\\data%03d.out", i); freopen(fdsafdsa2, "w", stdout);
//
// fclose(stdin), fclose(stdout);
// }
return 0;
}
1.设计题目
2.确定总数据范围
3.列出表格,代表各个子任务的任务范围。
如下图:
4.写出这道题的代码
5.造数据
提示:
(1)随机数
代码:
//unsigned long long
unsigned long long r(unsigned long long a, unsigned long long b){
return (unsigned long long)rand() * rand() * rand() * rand() * rand() * rand() % (b - a + 1) + a;
}
//long long
long long r(long long a, long long b){
return (long long)rand() * rand() * rand() * rand() * rand() * rand() % (b - a + 1) + a;
}
//int
int r(int a, int b){
return (int)rand() * rand() % (b - a + 1) + a;
}
其中 a 和 b 代表随机数据的范围。
如 r(1, 10000) 代表 1 到 10000 之间的随机数(含 1 和 10000)
要在主函数中添加一行代码:
srand((signed)time(0)); //随机种子
如果不加,数据就不是随机的。
还有,需要根据每个子任务的范围造输入数据。
例如:
#include
using namespace std;
#define lld long long
lld r(lld a, lld b){
return (lld)rand() * rand() * rand() * rand() * rand() * rand() % (b - a + 1) + a;
}
int main() {
long long a = r(1, 1000000000000000000ll), b = r(1, 1000000000000000000ll);
cout << a << " " << b;
return 0;
}
需要加上 freopen。
#include
using namespace std;
#define lld long long
lld r(lld a, lld b){
return (lld)rand() * rand() * rand() * rand() * rand() * rand() % (b - a + 1) + a;
}
int main() {
freopen("game001.in", "w", stdout);
long long a = r(1, 1000000000000000000ll), b = r(1, 1000000000000000000ll);
cout << a << " " << b;
return 0;
}
如果要批量制造数据,就需要用到for循环。
#include
using namespace std;
#define lld long long
lld r(lld a, lld b){
return (lld)rand() * rand() * rand() * rand() * rand() * rand() % (b - a + 1) + a;
}
int main() {
for(int i = 1; i <= 10; i ++){
char s1[15]; sprintf(s1, "game%03d.in", i); freopen(s1, "w", stdout);
long long a = r(1, 1000000000000000000ll), b = r(1, 1000000000000000000ll);
cout << a << " " << b;
}
return 0;
}
这样输入数据就造好了。
下面我们来看输出数据,只需要把刚刚的代码也加上for循环和freopen就可以了。
#include
using namespace std;
/*P1001 A + B Problem*/
int main() {
int a, b;
for(int i = 1; i <= 10; i ++){
char s1[15], s2[15]; sprintf(s1, "game%03d.in", i); sprintf(s2, "game%03d.out", i); freopen(s1, "r", stdin); freopen(s2, "w", stdout);
cin >> a >> b;
cout << a + b;
}
return 0;
}
这样输出数据就造好了。
6.测试点
需要对测试点进行测试,如:特殊数据/送分数据 按正常的骗分方法能否正确,造几组简单的数据手算,检查代码是否有误等
然后就是捆绑测试,需要把计分方式改为自定义,然后加入计分的代码,这一有一个自动生成的程序:
#include
using namespace std;
int main(){
int a = 24, b = 32, sco = 36;
printf("if (@status%d == AC)", a);
for(int i = a + 1; i <= b; i ++)
printf(" and (@status%d == AC)", i);
printf("; then\n");
printf(" @total_score = %d;\n @final_status = AC;\n @final_time = @time%d", sco, a);
for(int i = a + 1; i <= b; i ++)
printf(" + @time%d", i);
printf(";\n @final_memory = @memory%d", a);
for(int i = a + 1; i <= b; i ++)
printf(" + @memory%d", i);
printf(";\nelse\n @total_score = 0;\n @final_status = UNAC;\n @final_time = 0;\n @final_memory = 0;\nfi");
return 0;
}
其中 a 代表该子任务第一个测试点的编号,b 代表该子任务最后一个测试点的编号,sco 代表该组总分数,修改生成后直接复制到该子任务旁边的方框里,就可以实现捆绑计分。
如果有其它特殊的计分方式,可以参考自定义计分脚本
然后,你就成功出好了一道题并且造好了数据。
感谢观看