zoukankan      html  css  js  c++  java
  • 如何在考场上快速用C++写高级对拍器

    众所周知,在考场上写完一道题的“正解”,不和暴力对拍一下,谁也不敢说自己可以 (AC)
    然而,(Windows)批处理文件的循环经常写出 (bug) (起码我是这样)。

    怎么办呢?这时候就轮到我们的 (C++) 上场了。

    (C++) 写对拍器需要用到系统操作,全代码主要分为以下几个部分:

    1. 利用数据生成器(随机数大法好)、自己的程序、(std) 或者暴力,进行文件的读入读写。
    2. 读入两个文件并比较。
    3. 获得反馈。

    假设如今我们有如下这些东西:
    (get.cpp/exe): 数据生成器
    (T2.cpp/exe): 我们自己的程序
    (std.cpp/exe): 我们可以保证答案正确的程序
    (check.cpp/exe): 我们要编写的对拍器
    image.png

    Step 1 读写文件

    首先看文件的读写部分。在重复生成多组数据并跑出答案时,直接用我们常用 (freopen) 特别不方便,在这里我们使用 (Sprinf)
    (Sprintf) 函数可以大致看作 (Printf) 函数的升级版,但是其功能强大的多。这里不做过多介绍。

    创建一个 (char) 变量,作为对系统进行操作的"工具人"。 这里我命名为 (buf)。然后,利用 (sprintf)(Windows)(bat) 文件语言融合版,我们可以这么写:
    sprintf(buf, "get.exe > 1.in"); system(buf);
    后面的 (system) 表示对系统进行操作,双引号内这句话为 (Windows)批处理文件语法,表示 (get.exe)(1.in) 这个文件输入,箭头指向右边代表输入,指向左边代表读入。
    于是,对于我们自己的程序和 (std), 我们可以这样写:

    sprintf(buf, "T2.exe < 1.in > 1.out");
    system(buf); 
    sprintf(buf, "std.exe < 1.in > 2.out");
    system(buf); 
    

    (1.out)(2.out) 即为我们得到的两个程序的输出结果。

    Step 2 记录答案

    定义一个 (check) 函数,同时用数组记录下两个文件中的所有数字,若为字符串等较长类型,更换成 (char) 记录即可。
    这里直接使用简单的 (freopen) 完成。

    freopen("1.out", "r", stdin);
    while(scanf("%d", &a[++cnt1]) != EOF) ;
    fclose;
    freopen("2.out", "r", stdin);
    while(scanf("%d", &b[++cnt2]) != EOF) ;
    fclose; 
    

    一个十分简单的操作我们便将两个答案存在了 (a) 数组和 (b) 数组中。

    Step 3 答案比较

    这一步十分简单,直接 (for) 循环比较即可。当然也可以先比较一下 (cnt1)(cnt2) 是否相等。

    for(int i = 1; i <= cnt1; i++){
          if(b[i] != a[i]){
    	wrong_and_pause(); 
    	return 0; 
          }
    }
    

    其中的 (wrong) _ (and) _ (pause) 函数主要是我们用来在遇到错误时及时得到反馈并暂停程序,以防止 (hack) 数据被覆盖,方便我们及时查看。

    实现同样很 (easy):

    void wrong_and_pause(){
    	printf("Wrong!
    ");
    	system("pause"); 
    	return ; `
    }
    

    Step 4 个性化操作

    (C++) 对比 (bat) 的简易对拍器,最大的优势就在于我们可以很大程度的自定义自己的对拍器,比如输出两边答案等等。 自己优化即可。

    奉上完整对拍器代码:

    #include <bits/stdc++.h>
    #include <windows.h>
    using namespace std;
    #define N 1000010
    #define ll long long
    
    template <class T>
    inline void read(T& a){
    	T x = 0, s = 1;
    	char c = getchar();
    	while(!isdigit(c)){ if(c == '-') s = -1; c = getchar(); }
    	while(isdigit(c)){ x = x * 10 + (c ^ '0'); c = getchar(); }
    	a = x * s;
    	return ;
    }
    
    int a[N], cnt1 = 0;
    int b[N], cnt2 = 0; 
    char buf[1024]; 
    
    void wrong_and_pause(){
    	printf("Wrong!
    ");
    	system("pause"); 
    	return ; 
    }
    
    bool check(int x){
    	cnt1 = 0, cnt2 = 0;
    	memset(a, 0, sizeof(a));
    	memset(b, 0, sizeof(b)); 
    	freopen("1.out", "r", stdin);
    	while(scanf("%d", &a[++cnt1]) != EOF) ;
    	fclose;
    	freopen("2.out", "r", stdin);
    	while(scanf("%d", &b[++cnt2]) != EOF) ;
    	fclose; 
    	printf("%d %d
    ", a[1], b[1]); 
    	if(cnt1 != cnt2){
    		wrong_and_pause();  
    		return 0; 
    	}
    	for(int i = 1; i <= cnt1; i++){
    		if(b[i] != a[i]){
    			wrong_and_pause(); 
    			return 0; 
    		}
    	}
    	return 1; 
    }
    
    int main(){
    	for(int i = 1; i <= 1000; i++){
    		sprintf(buf, "get.exe > 1.in");
    		system(buf);
    		sprintf(buf, "T2.exe < 1.in > 1.out");
    		system(buf); 
    		sprintf(buf, "std.exe < 1.in > 2.out");
    		system(buf); 
    		if(check(1)){
    			printf("Right Answer!
    "); 
    		}
    		Sleep(700); 
    	}
    	return 0;
    }
    
    
    
    
    

    (rendered) (by) (Latex)

  • 相关阅读:
    Android开发
    Android随笔
    Android开发
    宁波大学NBU计算机大三下册期末考试
    2021浙江省大学生程序设计竞赛D题 Shortest Path Query(最短路+思维)
    NWERC 2020A Atomic Energy(背包+思维)
    CF1454E Number of Simple Paths(容斥+基环树)
    CF549F(分治+启发式合并)
    HDU5293 Tree chain problem (LCA+树链剖分+线段树)
    HDU156 The more, The Better(dp+背包)
  • 原文地址:https://www.cnblogs.com/wondering-world/p/13830057.html
Copyright © 2011-2022 走看看