赞
踩
题目来自于博主算法大师的专栏:最新华为OD机试C卷+AB卷+OJ(C++JavaJSPy) https://blog.csdn.net/banxia_frontend/category_12225173.html
公司用一个字符串来表示员工的出勤信息
absent:缺勤
late:迟到
leaveearly:早退
present:正常上班
现需根据员工出勤信息,判断本次是否能获得出勤奖,能获得出勤奖的条件如下:
缺勤不超过一次;
没有连续的迟到/早退;
任意连续7次考勤,缺勤/迟到/早退不超过3次。
用户的考勤数据字符串
记录条数 >= 1;
输入字符串长度 < 10000;
不存在非法输入;
如:
2
present
present absent present present leaveearly present absent
根据考勤数据字符串,如果能得到考勤奖,输出”true”;否则输出”false”,
对于输入示例的结果应为:
true false
输入
2
present
present present
输出
true true
输入
2
present
present absent present present leaveearly present absent
输出
true false
// 定义最大记录数为100,每条记录的最大长度为100 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_RECORDS 100 #define MAX_LENGTH 100 // 定义一个函数 // `can_receive_award`,用于判断给定的出勤记录数组是否满足获得出勤奖的条件 int can_receive_award(char records[][MAX_LENGTH], int count) { // 初始化缺勤次数计数器 int absent_count = 0; // 遍历整个出勤记录数组 for (int i = 0; i < count; i++) { // 检查当前记录是否为“absent”(缺勤) if (strcmp(records[i], "absent") == 0) { absent_count++; // 如果缺勤超过一次,则直接返回不能获得出勤奖(false) if (absent_count > 1) { return 0; } } // 检查当前记录是否为“late”或“leaveearly”(迟到/早退) if (strcmp(records[i], "late") == 0 || strcmp(records[i], "leaveearly") == 0) { // 如果当前记录是迟到/早退,并且上一条记录也是迟到/早退,则返回不能获得出勤奖(false) if (i > 0 && (strcmp(records[i - 1], "late") == 0 || strcmp(records[i - 1], "leaveearly") == 0)) { return 0; } } // 当遍历到第6条记录之后,开始检查连续7天内的违规情况 if (i >= 6) { int count_in_7_days = 0; // 遍历连续7天的记录 for (int j = i - 6; j <= i; ++j) { // 若当天不是正常上班("present"),则违规次数+1 if (strcmp(records[j], "present") != 0) ++count_in_7_days; } // 如果连续7天内违规次数超过3次,则返回不能获得出勤奖(false) if (count_in_7_days > 3) { return 0; // false } } } // 所有条件都满足后,返回能获得出勤奖(true) return 1; } int main() { // 读取用户输入的记录组数 int n; scanf("%d", &n); // 遍历每一组记录 for (int i = 0; i < n; i++) { // 初始化记录数组和记录数量计数器 char records[MAX_RECORDS][MAX_LENGTH]; int count = 0; // 逐条读取用户的考勤记录,直到遇到换行符或者无法读取为止 while (scanf("%s", records[count]) == 1) { count++; // 判断是否读取到换行符,如果是,则跳出循环 if (getchar() == '\n') break; } // 根据读取到的记录调用 `can_receive_award` 函数并输出结果 printf("%s ", can_receive_award(records, count) ? "true" : "false"); } return 0; }
这段代码是C语言中用于读取输入流(通常是标准输入,即键盘输入)的循环结构。while
循环会一直执行,只要从输入流成功读取一个字符串到数组records
中且返回值为1。
详细解释如下:
scanf("%s", records[records_size])
:scanf
是C语言中的格式化输入函数,这里的"%s"表示按照字符串格式读取输入。records
是一个字符数组,records[records_size]
代表将读取的字符串存放在数组的records_size
索引位置。注意,这里没有检查数组越界问题,实际使用时应确保records_size
小于数组长度。
== 1
:scanf
函数在成功读取并赋值时,会返回成功处理的参数个数。在这里,因为只有一个"%s"格式说明符,所以当成功读取一个字符串时返回1。如果遇到文件结束符(如按下回车键但未输入任何字符串)、读取错误或输入与格式不符等情况,scanf
会返回非1的值(通常是EOF或0)。
因此,整个while
循环的意思是:只要能成功从输入流读取一个字符串并存入records
数组中,就继续循环。这样可以连续不断地读取多个字符串,直到无法成功读取为止。
getchar()
是C语言中用于从标准输入(通常是键盘)读取单个字符的标准库函数。每次调用时,它会等待用户输入并返回一个字符。
在上述代码中:
while (scanf("%s", records[count]) == 1) {
count++;
if (getchar() == '\n')
break;
}
这段代码首先使用scanf
读取一个字符串到records
数组中,然后立即调用getchar()
来读取下一个字符。这里的目的是处理换行符的问题。当用户在输入字符串后按下回车键时,scanf
会读取整个字符串但不会读取回车符,而回车符会被留在输入缓冲区中。getchar()
在此处的作用就是读取并检查这个可能存在的回车符。如果读取到的字符是换行符\n
,则跳出循环,准备读取下一条记录。这样可以确保在处理多条记录时能够正确地分隔每条记录。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。