首页 > 其他分享 >做一道题的基本步骤

做一道题的基本步骤

时间:2024-03-19 13:46:42浏览次数:33  
标签:基本 子串 数字串 string int 步骤 一道 倍数 return

作为一个合格的编程爱好者,刷题是必不可少的。那么,我们应该如何去完成每一道题呢?下面我就告诉你做一道题的基本步骤。

这里我们以去年小学组省赛第三题(Topscoding)为例。

第一步:读题

读题无疑是很重要的一步。认真、仔细的读题可以帮助我们更深刻的理解题意,使我们能更快、更高效的完成代码。

我们来看一下这题的题面(标题省略):


本题请以文件输入输出方式进行提交,输入输出文件名是 string.in / string.out

题目背景

小可可和小多在研究数字串,他们在研究一个数字串的所有子串。

问题描述

给定一个长为 N 的数字串(即由若干 0 ∼ 9 的数字构成的字符串),请你回答有多少连续子串(即从该串中选出连续的若干个数字,可以包括前导 0 是 4 或 5 的倍数。如果同时是 4 和 5 的倍数,应当只被计算一次)。

输入格式

输入文件名为 string.in

第一行一个正整数 N,代表数字串的长度。

第二行一个长为 N 的数字串。

输出格式

输出文件名为 string.out

一行一个正整数,代表满足条件的子串数目。

样例

5
04321
6
解释#1

六个满足条件的串分别为 4, 432,32,0,04,0432。

样例#2

详见 选手文件夹 下的 string/string2.in/ans 文件。

数据范围

  • 对于 10% 的数据:满足 N = 1。
  • 对于 60% 的数据:满足 1 <= N <= 10^3。
  • 对于 100% 的数据:满足 1 <= N <= 10^6。

第一眼我们就看到了文件提示,这意味着我们的代码前面需要加上

//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);

当然,递交的时候注释需要去掉。

接下来是题目背景,一般情况下对题目影响不大,所以可以简单扫一眼,直接过掉。
然后就是问题描述,在看这个地方的时候一定不要放过每一句话,因为有可能你忽略的那句话就是题目的关键。
我们再把题目-问题描述拿过来看:


给定一个长为 N 的数字串(即由若干 0 ∼ 9 的数字构成的字符串),请你回答有多少连续子串(即从该串中选出连续的若干个数字,可以包括前导 0 是 4 或 5 的倍数。如果同时是 4 和 5 的倍数,应当只被计算一次)。


从中我们可以得知,输入数据里包含一个由若干数字组成的数字串,做了那么多题目的你们一定也想到:这题和字符串脱不了干系了。其次,我们要输出的是一个数(s),即为这个数字串里连续为4或5的倍数的可以有前导0的子串的个数
是不是很绕?简单总结一下子串的条件:

1.首先你要知道那些子串需要是连续的
每个子串:
2. 为4或5的倍数,可有前导0。

第二项怎么判断呢?
由于数据范围过大,我们肯定不能把子串转为int类型再做判断,这不仅麻烦还会超时。
你要知道,一个合格的编程者是需要掌握许多数学知识的。(如果一不小心刺痛了你向你道个歉~)
我们可以利用掌握的数学知识来解答:


4的倍数的数两位(/100)是4的倍数
5的倍数的数最后一位是05


这不就有思路了!
5的倍数很好判断,直接找0或5,再动s就好了(具体待会说)
4的话可以单独弄一个函数来判断后两位:

bool df(char x, char y) {
	if (int(x - '0') * 10 + int(y - '0') % 4 == 0) {
	    return 1;
	}
	return 0;
}

这不就OK了嘛。
至于如果同时是 4 和 5 的倍数,应当只被计算一次)。就用if-else好了
看吧,仔细琢磨琢磨题目,一些基本的思路不就出来了吗。
至于输入输出格式和样例都有解释,自己看好了,这里不做详解。
数据范围一定要看!很多思路都是搭建在数据上面的。

第二步:写代码

最激动人心的写代码部分来了。
经过上面的基本思路,我们可以大致确定代码的框架:

#include <bits/stdc++.h>
using namespace std;
long long n, s;
string a;
bool df(char x, char y) {
	if (((int(x - '0') * 10 + int(y - '0')) % 4) == 0) {
		return 1;
	}
	return 0;
}
int main() {
	//freopen("string.in", "r", stdin);
	//freopen("string.out", "w", stdout);
	cin >> n >> a;
	for (int i = 0; i < a.size(); i++) {
		//找子串
	}
	cout << s;
	return 0;
}

其实我们发现,思路有后,代码很简单的!
现在只有找子串部分使我们需要考虑的了。至于其他的,都考虑过了啊!

我们可以怎样写呢?
首先是if-else语句(避免重复)判断4、5倍数,由于5更简单,先写他吧:

if (a[i] == '0' || a[i] == '5') {
    s += (i + 1);
}

疑?为什么s是 += (i + 1)呢?
因为,只要末尾是这两个数,子串就是5的倍数。,并且排除了前导0的情况,直接加上他的下标不就不用重复算了嘛!至于+1,那是因为i是从0开始的。
else语句呢?

else {
    if (a[i] == '4' || a[i] == '8') {
        s++;
    }
    if (i != 0 && df(a[i - 1], a[i])) {
        s += i;
    }
}

第一个很好理解,因为个位4、8那他就可以单独成为一个“合格”的子串了。
第二个,也很好理解,毕竟i>0才能执行函数嘛!
那为什么第二个是s += i而不是s += (i + 1)呢?
那是因为你用的是两个if语句啊,+1在第一个已经过了
整体代码:

#include <bits/stdc++.h>
using namespace std;
long long n, s;
string a;
bool df(char x, char y) {
	if (((int(x - '0') * 10 + int(y - '0')) % 4) == 0) {
		return 1;
	}
	return 0;
}
int main() {
	//freopen("string.in", "r", stdin);
	//freopen("string.out", "w", stdout);
	cin >> n >> a;
	for (int i = 0; i < a.size(); i++) {
		if (a[i] == '0' || a[i] == '5') {
			s += (i + 1);
		} else {
			if (a[i] == '4' || a[i] == '8') {
				s++;
			}
			if (i != 0 && df(a[i - 1], a[i])) {
				s += i;
			}
		}
	}
	cout << s;
	return 0;
}

第三步:自测

先编译给的样例,没过就逐行找错、自运行、加log……
过了,最好自己出几个极端样例(因为普通样例没有意义)
完,递交,过了(没过就继续按照评测提示找错)。
这就差不多了吧。


第四步:总结

相对来说这题还是比较简单的。总的来说做一道题,首先是读题,非常重要。思路基本是从这来的。后期编写和修正也很重要,不过这里需要自己去尝试、实践,这样你才能收获更多。

最后,也祝大家能在编程之路上越走越稳,越走越远,越来越强大!

标签:基本,子串,数字串,string,int,步骤,一道,倍数,return
From: https://www.cnblogs.com/Yzc-wm/p/18082577

相关文章

  • CMakeLists.txt基本语法及使用
    1、cmake的说明cmake是一种高级编译配置工具当多个人用不同的语言或者编译器开发一个项目,最终要输出一个可执行文件或者共享库(dll,so等等)这时候便需要用到cmake。CMakeList.txt中指令不区分大小写。CMakeList.txt中的参数和变量是区分大小写,名称只能用字母,数字,下划线,破折号。......
  • echarts,实训1和三,会员基本信息分析
    <!DOCTYPEhtml><html><head><metacharset="utf-8"><!--引入ECharts脚本--><!--<第一步引入脚本>--><scriptsrc="js/echarts.js"></script></head><body>......
  • ATF基本术语
    学习资料来源于:https://www.bilibili.com/video/BV1Ky421i7Dp/?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=432ba293ecfc949a4174ab91ccc526d6 ATF是ARM开发和维护的,专门为Armv7及以后得cortex-A处理的firmware,目前最新版本为v2.9ATF是ARMT......
  • [学习记录]带头指针的单向链表的基本功能
    效果代码#include"stdio.h"#include"stdlib.h"typedefstructlinknode{ intdata; structlinknode*next;}LinkNode;LinkNode*CreateHeadNode(void);//创建头结点voidCreateNewNode(LinkNode*H);//创捷节点voidPrintList(LinkNode*H);//打印链表v......
  • 数学建模基本知识点
    1.建模准备2.建模基础算法3.经典模型4.论文书写......
  • MarkDown最基本语法
    c语言程序设计——实验报告一实验项目名称:实验一熟悉C语言运行环境实验项目类型:验证性实验日期:2023年3月14日一、实验目的下载安装Devc6.0程序。了解在该系统上如何进行编辑、编译、连接和运行一个C程序。通过运行简单的C程序了解C程序的特点。二、实验硬、软件环境Wi......
  • 微调LLama模型:具体步骤与代码实现
    微调LLama模型是一个涉及多个步骤的过程,包括数据准备、模型加载、设置优化器和损失函数、训练循环以及模型评估。下面,我们将详细介绍这些步骤,并给出相应的代码实现。步骤一:数据准备首先,我们需要准备用于微调的数据集。这通常包括一个输入文本序列和对应的标签或目标输出。......
  • 【操作系统】线程、程序、进程死锁的必要条件?如何避免死锁?死锁的预防,死锁的避免(银行
    目录线程、程序、进程死锁的必要条件?如何避免死锁?死锁的预防死锁的避免(银行家)死锁的检测进程-资源分配图死锁检测步骤死锁的解除线程、程序、进程进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行......
  • 学习笔记——C语言基本概念&运算符——(2)
    目录一、运算符1.1赋值运算符1.2算数运算符 1.3关系运算符1.5位运算符1.6 自增自减运算符1.7  复合运算符1.8逗号运算符1.9 三目运算符1.10 sizeof运算符附录:运算符优先性表一、运算符1>.按照操作数目分类:单目运算符,双目运算符,三目运算符。2>......
  • 数学建模--MATLAB基本使用
    1.线性方程组这个是一个线性方程组(属于线性代数的范畴),Ax=b类型的方程,如果使用MATLAB进行求解,就需要分别表示A矩阵(线性方程组未知数前面的系数),b矩阵(表示等式右边的结果),inv是这个软件里面的一个函数,用来进行求解A的逆矩阵,因为Ax=b,那么x=A-1次方乘上b另外,我们也可以使用这个......