OJ平台代码模板自动生成

本文介绍了如何分析编程竞赛数据的规律,以Java为例,详细讲解了输入输出的不同类型,如读取整数、数组、二维数组等,并提供了相应的代码模板。通过深度分析数据,发现自动化生成模板的可行性,鼓励读者参与CSDN编程竞赛并分享了Python实现模板生成的思路。
摘要由CSDN通过智能技术生成


前言

经常使用CSDN的小伙伴应该知道, 最近CSDN举办了好几期编程竞赛, 其中的编程模板, 都是有python脚本自动生成的, 这篇文章, 用以记录编程模板自动生成的开发过程.

我们以 java 语言为例进行讲解.

一、分析数据

要想自动化, 首先得发现数据的规律. 分析题库中的题目发现, 可以按照输入类型进行划分, 以下是可能的几个类型:

1、输入一个整数
2、输入一个定长的整数数组
3、输入一个变长的整数数组
4、输入一个定长的二维数组
5、输入一个行固定,列可变的二维数组
6、输入一个列固定,行可变的二位数组
7、输入多个整数
......

同样, 对于输出的数据, 也可以按类型划分, 以下是常见的几种可能的类型:

这里以整数为例

1、输出一个整数
2、输出一个整数数组
3、输出一个二维的整数数组
......

只要我们时间足够多, 就可以实现全部输入类型

二、解析输入

Java技能树的第一道题: A+B 为例
请添加图片描述

从输入数据上可以看出,该题属于输入多个整数类型

我们先来看看, Java 从命令行读取一个整数的代码:

读取一个整数

Scanner scan = new Scanner(System.in);
String str_0 = scan.nextLine().trim();
int a = Integer.parseInt(str_0);

这是一行一个整数的情况

读取多行整数

如果有多行, 每行都只有一个整数, 例如:

输入:
1
2
3

那我们只需要修改下变量名, 多读取几行就行了, 如:

Scanner scan = new Scanner(System.in);

String str_0 = scan.nextLine().trim();
int a = Integer.parseInt(str_0);

String str_1 = scan.nextLine().trim();
int b = Integer.parseInt(str_1);

String str_2 = scan.nextLine().trim();
int c = Integer.parseInt(str_2);

是不是, 茅塞顿开, 原来这是有规律的 !

读取一行中的多个整数

那如果是一行中有多个整数呢?

也很简单, 不信你看 :

Scanner scan = new Scanner(System.in);

String str_0 = scan.nextLine();
String[] line_list_0 = str_0.trim().split(" ");        
ArrayList<Integer> arr_temp = new ArrayList<>();
for(int i = 0; i < line_list_0.length; i++){
    arr_temp.add(Integer.parseInt(line_list_0[i]));
}

int a = arr_temp.get(0);
int b = arr_temp.get(1);

同理, 读取一个整型数组 :

Scanner scan = new Scanner(System.in);

String str_0 = scan.nextLine();
String[] line_list_0 = str_0.trim().split(" ");        
ArrayList<Integer> arr = new ArrayList<>();
for(int i = 0; i < line_list_0.length; i++){
    arr.add(Integer.parseInt(line_list_0[i]));
}

这里都不需要考虑是定长数组还是变长数组

如果是写C语言的编程模板,就需要考虑变长数组需要动态分配内存的情况

那么, 读取一个二维数组是怎样的呢?

请看 :

Scanner scan = new Scanner(System.in);

String str_0 = scan.nextLine().trim();
int q = Integer.parseInt(str_0);

ArrayList<ArrayList<Integer>> arr = new ArrayList<>();
for(int i = 0; i < q; i++){
    String str_3 = scan.nextLine();
    String[] line_list_3 = str_3.trim().split(" ");        
    ArrayList<Integer> temp_3 = new ArrayList<>();
    for(int j = 0; j < line_list_3.length; j++){
        temp_3.add(Integer.parseInt(line_list_3[j]));
    }
    arr.add(temp_3);
}

这里也不需要考虑列数 (C语言是需要考虑的) , 其中, q 表示输入数据的行数

其他的输入类型, 这里就不一一列举了

三、解析输出

相对解析输入来说, 解析输出就要简单很多

打印一个整数

int result = solution(n, vector);
System.out.println(result);

打印一个整数数组

ArrayList<Integer> result = solution(n, q, nums, arr);

for (int i = 0; i < result.size(); i++){
    System.out.println(result.get(i));
}

打印二维数组也是同理, 这里留给读者自己尝试

四、完整模板

以下是其中一个例子:

## 输入描述
第一行输入宝物的数量n(1<n<100)和可选择宝物的总质量M(0<=M<=1000)。 
以下n行每行输入两个数m和v(1<m<100, 1<v<100),表示这n个宝物其各自的重量和价值。

## 输入样例
5 10
2 3
5 3
4 5
6 2
4 2

import java.util.ArrayList;
import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        
        String str_0 = scan.nextLine();
        String[] line_list_0 = str_0.trim().split(" ");        
        ArrayList<Integer> arr_temp = new ArrayList<>();
        for(int i = 0; i < line_list_0.length; i++){
            arr_temp.add(Integer.parseInt(line_list_0[i]));
        }
    

        int n = arr_temp.get(0);
		int M = arr_temp.get(1);

        
        ArrayList<ArrayList<Integer>> vector = new ArrayList<>();
        for(int i = 0; i < n; i++){
            String str_2 = scan.nextLine();
            String[] line_list_2 = str_2.trim().split(" ");        
            ArrayList<Integer> temp_2 = new ArrayList<>();
            for(int j = 0; j < line_list_2.length; j++){
                temp_2.add(Integer.parseInt(line_list_2[j]));
            }
            vector.add(temp_2);
        }
    

        scan.close();

        int result = solution(n, M, vector);

        System.out.println(result);

    }

    public static int solution(int n, int M, ArrayList<ArrayList> vector){
        int result = 0;

        // TODO: 请在此编写代码

        return result;
    }
}

细心的同学应该发现了, 我这里都是以整数为例子, 其他类型的变量, 也是一样的, 只需判断输入数据的变量类型即可, 如:

def is_float_num(str):
    s=str.split('.')
    if len(s)>2:
        return False
    else:
        for si in s:
            if not si.isdigit():
                return False
        return True


def is_number(i):
    try:
        int(i)
        return True
    except:
        return False

def parse_input_one(item, var_name, input_var_idx = 0, assgin_var_type=None):
    var_type = None
    var_def = None
    var_input = None
    
    if assgin_var_type is not None:
        var_type = assgin_var_type
        var_def_ = f"{assgin_var_type} {var_name} = str_{input_var_idx}"
    else:
        if is_number(item):
            var_type = "int"
            var_def_ = f"int {var_name} = Integer.parseInt(str_{input_var_idx})"
        elif is_float_num(item):
            var_type = "float"
            var_def_ = f"float {var_name} = Float.parseFloat(str_{input_var_idx})"
        else:
            var_type = "String"
            var_def_ = f"String {var_name} = str_{input_var_idx}"
    
    var_def = f"{var_type} {var_name}"
    input_template = f"String str_{input_var_idx} = scan.nextLine().trim();"
    var_input = f"{input_template}\n\t\t{var_def_}"
    return var_type,var_name, var_def, var_input

我这里只考虑了常用的三种类型, 如果是其他类型, 可以通过参数assgin_var_type来控制.

以上模板生成的脚本代码, 是使用python来实现的.

总结

1、深度分析数据后才能发现数据的规律

一开始leader将这个jira分给我的时候, 我觉得这模板代码没法自动生成, 很是抗拒
自己写了几个 python 的 oj 模板后才发现这确实是有规律可循的

2、年轻人不要浮躁

OJ比赛感兴趣的同学, 可以参加 CSDN编程竞赛第四期
若发现 OJ 模板有任何问题, 可直接在评论区反馈

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ToTensor

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值