10 手把手带你从 OJ 练题 (Zero Judge)

相信很多新手在第一次听到老手建议去不同的线上评测平台「刷题目」时,总会一头雾水的不知道要怎麽练习,因此想各位展示要如何从 0 到 1 在 Online Judge 上写出第一个题目!

本来想要用在ZeroJudge的第一个题目当作示范,但想到本系列文章是 APCS,因此题目决定是目前在 ZeroJudge 公布的最後一次实作题的第一题「g275: 1. 七言对联」。(感谢 cthbst 提供测试资料及上传 ZOJ)

https://ithelp.ithome.com.tw/upload/images/20210924/20103852QAfkaKB0SP.png

  1. 先读懂题目

每一个题目基本上会有「题目叙述」、「输入输出说明」、「范例测试资料」及「配分机制」四大部分,但当看到任何一个题目时,不要先看输入或输出,虽然可以藉由输入输出猜出原题目的题意,但不要本末倒置变成会错题意的窘境。

题目叙述
中文依照发音方式可以分为平声与仄声,假设我们把平声标记为 0 而仄声标记为 1
一个七言对联包含两个句子,每个句子包含恰好七个字

七言对联有三个限制:
A: 二四不同二六同:每一句第二、四个字必须不同平仄,而第二、六个字必须相同平仄
B: 仄起平收:第一句的结尾必须为仄声,第二句的结尾必须为平声
C: 上下相对:第一、二句的第二、四、六个字平仄必须不同

给你 n 组对联,分别用0, 1 代表平仄,请输出它违反了哪几条规则
若以上规则皆无违反,请输出None

是个只要有国文平仄基础就能懂的题目呢

  1. 确认输入输出

在输入及输出部分,不同题目会有不同的形态,有时需要特别注意。在这题的输入输出都很容易理解,若有解释不清楚的部分可以参考题目给的范例输入/输出。

输入说明
输入一个正整数 n (1≤n≤30) 代表对联数量,接下来有 2n 行,每行有 7 个数字,数字不是 0 就是 1

输出说明
对於每个对联,输出一行表示它违反了哪些规则,若三个规则都遵守则输出 None

  1. 透过给分机制当作参考想出解法

在比较困难的题目中,题目会给出一些
因为本题没有任何的给分机制,所以没有任何的参考。但因为这题的解法够直觉也够简单,因此只需要照着题目实作,分别判断 ABC 三个条件,在全符合的时候输出 None,而当有任何一个部分不符合时则是印出不符合的字母(记得每做一次都要换行)。

  1. 准备好写程序的环境(IDE, 编辑器+编译器...)

虽然我现在的电脑没有装任何 Linux 的虚拟机器,如果想要熟悉考试环境的话建议还是建议多使用熟悉喔。我自己的开发环境比较习惯使用 Terminal,而编辑器则是 vim 和 VSCode 为主。秀出桌面好害羞(/////

https://ithelp.ithome.com.tw/upload/images/20210924/20103852orKPIAZiM8.png

  1. 解题!

在确定是否合法的部分,我分别写了三个不同函式去判定 ABC 分别是否合法。

bool isA(const int c[2][7]) {
	for(int i = 0; i < 2; ++i)
		if(c[i][1] == c[i][3] || c[i][1] != c[i][5]) return false;
	return true;
}

bool isB(const int c[2][7]){
	return (c[0][6] == 1 && c[1][6] == 0);
}

bool isC(const int c[2][7]){
	for(int i = 1; i <= 5; i += 2)
		if(c[0][i] == c[1][i]) return false;
	return true;
}

在主程序的部分则是依照提议创出能够容纳两个平仄的二维 int 矩阵 (也可以用bool),并创造出三个 bool 分别储存三个规定的合法性,再依照题意输出,最後整个程序再用输入笔数 (n) 包起来。

int main(){
	int n;
	cin >> n;
	while(n--){
		int couplet[2][7];
		for(int i = 0; i < 2; ++i)
			for(int j = 0; j < 7; ++j)
				cin >> couplet[i][j];
		bool a = isA(couplet), b = isB(couplet), c = isC(couplet);
		if(a && b && c)
			cout << "None\n";
		else
			cout << (a?"":"A") << (b?"":"B") << (c?"":"C") << "\n";
	}

	return 0;
}
  1. 利用测试资料测试 & 缴交

除了题目给的测试资料外,也要根据题目给的范围创造出有可能会需要检查的测试资料。

SkyHong$ ./deafult.out
2
0 1 1 0 0 0 1
1 0 1 1 0 1 1
0 1 0 0 0 0 1
0 0 0 0 0 1 1

AB
ABC

确定没错後上传到 Zero Judge,最後 Accept 了!

https://ithelp.ithome.com.tw/upload/images/20210924/20103852ljUEFxSRz9.png


当题目写完後,可以把自己写的程序整理起来,或是可以放在自己的部落格,再放上写题目时遇到的瓶颈、学到的东西和要注意的地方。当写题目的量一点一点的变多时,成就感也会越来越高,也会越来越有自信喔!加油!


<<:  Day 9. 来Build游戏看看

>>:  [DAY 09]深度学习模型实作 -- 前导

不只懂 Vue 语法:为什麽需要使用 $nextTick ?

问题回答 $nextTick 的作用是等待画面更新後才执行程序,因为有些时候我们需要操作画面上的 D...

D14 重新设定create date & 上传功能测试

将create date的auto_now_add删除 并加入upload相关栏位 DateTime...

Day6 简介 ICS 中的控制器 Controller-PLC、PAC、RTU

PLC 可程序逻辑控制器 针对工业环境设计的逻辑控制系统,可以在记忆体中可执行以下指令如逻辑运算(...

ServiceNow CIS-SIR Exam - The Real World Experience

ServiceNow CIS-SIR Exam - The Real World Experienc...

Day 8 ROS Client Library 与 Roscpp

ROS Client Library ROS 最为一款广为人知的机器人作业系统,当然也能让很多种程序...