ACM模式练题技巧——C语言
1 数字输入
华为软件机试是采用ACM模式,这种模式需要根据题目要求,按照规定的格式自己手动写输入和输出的代码,如果没有充分准备,考试的时候就有可能会在输入输出这块卡很久,浪费考试的时间。
下面总结了一些常见的输出输出格式,以我们常用的几种语言,给出对应格式的编码模板,掌握的这些输入输出模板,可以让我们在考试的时候快速完成输入输出代码的编写,节省出更多的时间思考和编写逻辑代码。
1.1 多组空格分隔的两个正整数
输入包括两个正整数a,b(1 <= a, b <= 10^9),输入数据包括多组,示例如下:
1 5 10 20
C语言
// 直接处理的情况,适用于比较简单的题型 #include <stdio.h> int main() { int a,b; while(scanf("%d %d",&a, &b) != EOF) {//注意while处理多个case printf("%d\n",a+b); } return 0; } // 先保存起来再处理的场景,适用于较复杂的题型,需要在while外部处理数据,层次更清晰 #include <stdio.h> #include <stdint.h> #define MAX_NUM 100 int main() { int inputNum = 0; int a[MAX_NUM], b[MAX_NUM]; while (scanf("%d %d", &a[inputNum], &b[inputNum]) != EOF) { inputNum++; } for (int i = 0; i < inputNum; i++) { printf("%d\n", a[i] + b[i]); } return 0; }
1.2 第一行组数后接空格分隔的两个正整数
输入第一行包括一个数据组数t(1 <= t <= 100)接下来每行包括两个正整数a,b(1 <= a, b <= 10^9)示例如下
2 1 5 10 20
C语言
#include <stdio.h> #include <stdint.h> int main() { int groupNum; int a, b; if (scanf("%d", &groupNum) == EOF) { return -1; } for (int i = 0; i < groupNum; i++) { if (scanf("%d %d", &a, &b) == EOF) { break; } printf("%d\n", a + b ); } return 0; }
1.3 空格分隔的两个正整数,当都为0时结束
输入包括两个正整数a,b(1 <= a, b <= 10^9),输入数据有多组, 如果输入为0 0则结束输入
示例如下:
1 5 10 20 0 0
C语言
#include <stdio.h> #include <stdint.h> int main() { int a, b; while (scanf("%d %d", &a, &b) != EOF) { if (a == 0 && b == 0) { break; } printf("%d\n", a + b); } return 0; }
1.4 每行第一个为个数,后面带空格分割,为0时结束
输入数据包括多组。每组数据一行,每行的第一个整数为整数的个数n(1 <= n <= 100), n为0的时候结束输入。接下来n个正整数,即需要求和的每个正整数。
示例如下:
4 1 2 3 4 5 1 2 3 4 5 0
C语言
#include <stdio.h> #include <stdint.h> #define MAX_NUM 100 int main() { int dataNum; while (scanf("%d", &dataNum) != EOF) { if (dataNum == 0) { break; } int sum = 0; int a; for (int i = 0; i < dataNum; i++) { if (scanf("%d", &a) == EOF) { break; } sum += a; } printf("%d\n", sum); } return 0; }
1.5 第一行为组数,后面每行第一个数为个数,后面数据带空格分割
输入的第一行包括一个正整数t(1 <= t <= 100), 表示数据组数。接下来t行, 每行一组数据。每行的第一个整数为整数的个数n(1 <= n <= 100)。接下来n个正整数, 即需要求和的每个正整数。
示例如下
2 4 1 2 3 4 5 1 2 3 4 5
C语言
#include <stdio.h> #include <stdint.h> int main() { int groupNum; if (scanf("%d", &groupNum) == EOF) { return -1; } for (int groupId = 0; groupId < groupNum; groupId++) { int dataNum; if (scanf("%d", &dataNum) == EOF) { break; } int sum = 0; int a; for (int i = 0; i < dataNum; i++) { if (scanf("%d", &a) == EOF) { break; } sum += a; } printf("%d\n", sum); } return 0; }
1.6 每行第一个为个数,后面数据带空格分隔
输入数据有多组, 每行表示一组输入数据。每行的第一个整数为整数的个数n(1 <= n <= 100)。接下来n个正整数, 即需要求和的每个正整数。
示例如下
4 1 2 3 4 5 1 2 3 4 5
C语言
#include <stdio.h> #include <stdint.h> #define MAX_NUM 100 int main() { int dataNum; while (scanf("%d", &dataNum) != EOF) { int sum = 0; int a; for (int i = 0; i < dataNum; i++) { if (scanf("%d", &a) == EOF) { break; } sum += a; } printf("%d\n", sum); } return 0; }
1.7 多组空格分隔的正整数
输入数据有多组, 每行表示一组输入数据。
每行不定有n个整数,空格隔开。(1 <= n <= 100)。
示例如下
1 2 3 4 5 0 0 0 0 0
C语言
#include <stdio.h> #include <stdint.h> int main() { int sum = 0; int a; while (scanf("%d", &a) != EOF) { sum += a; if (getchar() == '\n') { printf("%d\n", sum); sum = 0; } } return 0; }
2 字符串输入
2.1 第一行为整数n,第二行为n个字符串,空格隔开
输入有两行,第一行n
第二行是n个字符串,字符串之间用空格隔开
5 c d a bb e
C语言
#include <stdio.h> #include <stdint.h> #define MAX_NUM 100 #define MAX_LEN 1000 int main() { int n = 0; char str[MAX_NUM][MAX_LEN]; if (scanf("%d", &n) == EOF) { return -1; } for (int i = 0; i < n; i++) { if (scanf("%s", str[i]) == EOF) { break; } } return 0; }
2.2 多个测试用例,每个测试用例一行,空格分隔
多个测试用例,每个测试用例一行。
每行通过空格隔开,有n个字符,n<100
a c bb f dddd nowcoder
C语言
#include <stdio.h> #include <stdint.h> #define MAX_NUM 100 #define MAX_LEN 1000 int main() { char str[MAX_NUM][MAX_LEN]; while (scanf("%s", str[0]) != EOF) { int n = 1; while (getchar() != '\n') { scanf("%s", str[n]); n++; continue; } for (int i = 0; i < n; i++) { printf("%s ", str[i]); } printf("\n"); } return 0; }
2.3 多个测试用例,每个测试用例一行,逗号分隔
多个测试用例,每个测试用例一行。每行通过,隔开,有n个字符,n<100
a,c,bb f,dddd nowcoder
C语言
#include <stdio.h> #include <stdint.h> #include <string.h> #define MAX_NUM 100 #define MAX_LEN 1000 int main() { char tmp[MAX_LEN]; char str[MAX_NUM][MAX_LEN]; while (scanf("%s", tmp) != EOF) { int n = 0; char *ptr = strtok(tmp, ","); while(ptr != NULL) { strcpy(str[n], ptr); ptr = strtok(NULL, ","); n++; } for (int i = 0; i < n - 1; i++) { printf("%s,", str[i]); } printf("%s", str[n - 1]); printf("\n"); } return 0; }
各类输入输出练习,可以通过以下链接练习
https://ac.nowcoder.com/acm/contest/5652#question
2 排序
C语言不像其他语言,没有专门的方法给数组或者字符串排序,但也有一个快速排序的函数可以使用,就是qsort,掌握qsort函数的用法,在做排序相关的题目时,就不需要自己写排序函数,提高编码效率。以下总结可以学习下,重点掌握数组、字符串、结构体的排序方法。
qsort函数使用方法总结(详细全面+代码)_牛客网 (nowcoder.com)
3 考试常用库函数
3.1 字符串相关库函数
字符串是常考题型,掌握一些常用的库函数,可以有效提高编码效率,可以通过以下链接学习
常用的字符串相关库函数如下表,建议熟练掌握:
memcmp |
memcpy |
memset |
strcat |
strchr |
strcmp |
strcpy |
strlen |
strrchr |
strstr |
strtok |
3.2 字符相关库函数
字符相关库函数主要作用是判断当前字符的类型及大小写转换
考试常用的有以下函数
isalpha |
isdigit |
islower |
isupper |
isxdigit |
isspace |
tolower |
toupper |
4 栈和队列的简单写法
编程考试中,C语言相比于语言来说,最大的不足就是没有定义好的数据结构可以直接使用,需要自己编写代码,这样就会比其他语言多花不少时间,好在考试对数据结构操作的要求比较简单,不用写的很完善,可以写的简单一些,减少写代码的时间,栈和队列是考试中经常用到的数据结构,以下是C语言的简单实现。
4.1 栈
int stack[MAX_LEN]; int top = 0; void StackInit(void) { top = 0; } int StackPush(int e) { if (top >= MAX_LEN - 1) { return -1; } stack[top] = e; top++; return 0; } int StackPop(int *e) { if (top == 0) { return -1; } *e = stack[top - 1]; top--; return 0; }
4.2 队列
#define MAX_LEN 1000 int queue[MAX_LEN]; int head = 0; int tail = 0; void QueueInit(void) { head = 0; tail = 0; } int QueueIsEmpty(void) { return head == tail; } int QueueIsFull(void) { return (tail + 1) % MAX_LEN == head; } int QueueAdd(int e) { if (QueueIsFull()) { return -1; } queue[tail] = e; tail = (tail + 1) % MAX_LEN; return 0; } int QueueGet(int *e) { if (QueueIsEmpty()) { return -1; } *e = queue[head]; head = (head + 1) % MAX_LEN; return 0; }
5 典型题练习推荐
华为机试题目
https://www.nowcoder.com/exam/oj/ta?page=1&tpId=37&type=37
数组 | HJ97,HJ105,HJ3,HJ64 |
字符串 | HJ13,HJ18,HJ39,HJ19,HJ71,HJ29,HJ85 |
排序 | HJ68,HJ6,HJ30,HJ31,HJ34 |
队列 | HJ24,HJ88, |
链表 | HJ90,HJ48,HJ51 |
栈 | HJ50、HJ54、HJ70 |
二分法 | HJ107 |
BFS | HJ43 |
DFS | HJ67 |