用户入网定期复评
华为OD机试双机位C卷 - 华为OD上机考试双机位C卷 100分题型
华为OD机试双机位C卷真题目录点击查看: 华为OD机试双机位C卷真题题库目录|机考题库 + 算法考点详解
题目描述
用户开立支付账户,在开户完成后立即对用户进行一次风险模型评级,输出一个评分风险评分范围1-100,等区间的分为5个等级,1-19为等级1,20-39为等级2,40-59为等级3,60-79为等级4,80-100为等级5,系统每天会任务对全量入网用户进行计算复评时间,输出评分给出新的风险等级。复评规则如下:
- 等级1每36个月重评一次。
- 等级2每12个月重评一次。
- 等级3每8月重评一次。
- 等级4每6个月重评一次。
- 等级5每3个月重评一次。
每个月固定按照30天计算下次日期,即每3个月对应下次日期为90天后,其它同理。
如果上次评级时间和本次任务时间差,超过了该等级应该重评的时间,说明上次漏评,那么该等级自动评级提升1等级,按照新的等级计算下次一定重评时间,最高为等级5.
输入描述
输入共m+1行,每行信息如下:
- 第一行为m和task_date,中间以空格分割,m表示全量用户数,task_date表示本次评级任务启动时间。
- 第2行到m+1行为m个用户信息,按顺序每个用户的信息格式为name(用户姓名),last_rating_time(上次评级的时间,整数,表示从2000年1月1日起的天数),score(用户上一次的评分),以空格分割。
- name为仅小写字母组成的字符串,字符串长度范围为[1-500]
输出描述
输出当前任务时间与上次复评时间小于等于5天的评级用户,逗号分割输出。
- 按照复评时间升序排序
- 用户复评时间一致按照姓名升序排序。
用例1
输入
none
1 100
zhangsan 8 87
输出
none
zhangsan
题解
思路:模拟 + 自定义排序
- 题目本质求的是每个用户在今天之前上一次应当测评的时间。
- 对于每个用户给出的
last_rating_time和score要计算今天之前上一次测评的时间的逻辑如下:- 定义
lastTestTime存储上次测评时间,初始设置lastTestTime = lastRatingTime。通过score计算用户等级grade, 计算当前和初始测评时间差diff = now - last_rating_time. - 当
diffTime - getGradeIntervalTime(grade) > 0时重复执行以下操作:- 更新剩余时间
diffTime -= getGradeIntervalTime(grade) - 更新最新上次测评时间
lastTestTime += getGradeIntervalTime(currentGrade) - 更新最新级别
grade = min(grade + 1, 5)
- 更新剩余时间
- 当退出循环时,此时
lastTestTime就是用户距离最近上次测评时间,然后判断和当前时间差值是否在5及以内,加入结果数组中。
- 定义
- 通过2的逻辑对结果数组进行自定义排序,然后输出结果即可。
C++
c++
#include<iostream>
#include<vector>
#include<string>
#include <utility>
#include <sstream>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
struct Info {
string name;
// 上次测评时间
int lastTime;
Info(string name, int lastTime):name(name), lastTime(lastTime){
}
};
int getGrade(int score) {
if (score <= 19) {
return 1;
} else if (score <= 39) {
return 2;
} else if (score <= 59) {
return 3;
} else if (score <= 79) {
return 4;
} else {
return 5;
}
return -1;
}
int getGradeIntervalTime(int grade) {
if (grade == 1) {
return 36 * 30;
} else if (grade == 2) {
return 12 * 30;
} else if (grade == 3) {
return 8 * 30;
} else if (grade == 4) {
return 6 * 30;
} else {
return 3 * 30;
}
}
// 时间升序,名字升序
bool cmp(Info& a, Info& b) {
if (a.lastTime == b.lastTime) {
return a.name < b.name;
}
return a.lastTime < b.lastTime;
}
int main() {
int m, now;
cin >> m >> now;
vector<Info> res;
for (int i = 0; i < m; i++) {
string name;
int lastRatingTime,score;
cin >> name >> lastRatingTime >> score;
int diffTime = now - lastRatingTime;
int lastTestTime = lastRatingTime;
int currentGrade = getGrade(score);
// 小于0说明复评时间在当前之后
while (diffTime - getGradeIntervalTime(currentGrade) > 0) {
// 减去和当前时间剩余天数
diffTime -= getGradeIntervalTime(currentGrade);
// 更新上次评测时间
lastTestTime += getGradeIntervalTime(currentGrade);
// 最大等级为5
currentGrade = min(currentGrade + 1, 5);
}
if (now - lastTestTime <= 5) {
res.push_back({name, lastTestTime});
}
}
// 自定义排序
sort(res.begin(), res.end(), cmp);
// 输出结果
for (int i = 0; i < res.size(); i++) {
cout << res[i].name;
if (i != res.size() -1) {
cout << ",";
}
}
return 0;
}
JAVA
java
import java.util.*;
public class Main {
static class Info {
String name;
// 上次测评时间
int lastTime;
Info(String name, int lastTime) {
this.name = name;
this.lastTime = lastTime;
}
}
// 获取等级
static int getGrade(int score) {
if (score <= 19) return 1;
else if (score <= 39) return 2;
else if (score <= 59) return 3;
else if (score <= 79) return 4;
else return 5;
}
// 当前等级测评间隔时间
static int getGradeIntervalTime(int grade) {
if (grade == 1) return 36 * 30;
else if (grade == 2) return 12 * 30;
else if (grade == 3) return 8 * 30;
else if (grade == 4) return 6 * 30;
else return 3 * 30;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int now = sc.nextInt();
List<Info> res = new ArrayList<>();
for (int i = 0; i < m; i++) {
String name = sc.next();
int lastRatingTime = sc.nextInt();
int score = sc.nextInt();
int diffTime = now - lastRatingTime;
int lastTestTime = lastRatingTime;
int currentGrade = getGrade(score);
// 小于0说明复评时间在当前之后
while (diffTime - getGradeIntervalTime(currentGrade) > 0) {
// 减去和当前时间剩余天数
diffTime -= getGradeIntervalTime(currentGrade);
// 更新上次剩余时间
lastTestTime += getGradeIntervalTime(currentGrade);
// 最大等级为5
currentGrade = Math.min(currentGrade + 1, 5);
}
if (now - lastTestTime <= 5) {
res.add(new Info(name, lastTestTime));
}
}
// 排序:时间升序,名字升序
Collections.sort(res, (a, b) -> {
if (a.lastTime == b.lastTime) {
return a.name.compareTo(b.name);
}
return a.lastTime - b.lastTime;
});
for (int i = 0; i < res.size(); i++) {
System.out.print(res.get(i).name);
if (i != res.size() - 1) System.out.print(",");
}
}
}
Python
python
import sys
# 获取等级
def get_grade(score):
if score <= 19:
return 1
elif score <= 39:
return 2
elif score <= 59:
return 3
elif score <= 79:
return 4
else:
return 5
# 获取间隔时间
def get_interval(grade):
if grade == 1:
return 36 * 30
elif grade == 2:
return 12 * 30
elif grade == 3:
return 8 * 30
elif grade == 4:
return 6 * 30
else:
return 3 * 30
data = sys.stdin.read().split()
m = int(data[0])
now = int(data[1])
idx = 2
res = []
for _ in range(m):
name = data[idx]
last_time = int(data[idx + 1])
score = int(data[idx + 2])
idx += 3
diff = now - last_time
last_test_time = last_time
grade = get_grade(score)
# 小于0说明复评时间在当前之后
while diff - get_interval(grade) > 0:
# 更新剩余时间
diff -= get_interval(grade)
# 更新上次测评时间
last_test_time += get_interval(grade)
# 更新等级
grade = min(grade + 1, 5)
if now - last_test_time <= 5:
res.append((name, last_test_time))
# 排序
res.sort(key=lambda x: (x[1], x[0]))
# 输出
print(",".join([x[0] for x in res]))
JavaScript
js
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let input = [];
rl.on('line', function (line) {
input.push(line.trim());
});
rl.on('close', function () {
let [m, now] = input[0].split(' ').map(Number);
function getGrade(score) {
if (score <= 19) return 1;
else if (score <= 39) return 2;
else if (score <= 59) return 3;
else if (score <= 79) return 4;
else return 5;
}
function getInterval(grade) {
if (grade === 1) return 36 * 30;
else if (grade === 2) return 12 * 30;
else if (grade === 3) return 8 * 30;
else if (grade === 4) return 6 * 30;
else return 3 * 30;
}
let res = [];
for (let i = 1; i <= m; i++) {
let [name, lastTime, score] = input[i].split(' ');
lastTime = Number(lastTime);
score = Number(score);
let diff = now - lastTime;
let lastTestTime = lastTime;
let grade = getGrade(score);
// 小于0说明复评时间在当前之后
while (diff - getInterval(grade) > 0) {
diff -= getInterval(grade);
lastTestTime += getInterval(grade);
grade = Math.min(grade + 1, 5);
}
if (now - lastTestTime <= 5) {
res.push([name, lastTestTime]);
}
}
// 排序:时间升序,名字升序
res.sort((a, b) => {
if (a[1] === b[1]) {
return a[0].localeCompare(b[0]);
}
return a[1] - b[1];
});
// 输出
console.log(res.map(x => x[0]).join(","));
});
Go
go
package main
import (
"fmt"
"sort"
)
type Info struct {
name string
lastTime int
}
// 获取等级
func getGrade(score int) int {
if score <= 19 {
return 1
} else if score <= 39 {
return 2
} else if score <= 59 {
return 3
} else if score <= 79 {
return 4
}
return 5
}
// 获取间隔时间
func getInterval(grade int) int {
if grade == 1 {
return 36 * 30
} else if grade == 2 {
return 12 * 30
} else if grade == 3 {
return 8 * 30
} else if grade == 4 {
return 6 * 30
}
return 3 * 30
}
func main() {
var m, now int
fmt.Scan(&m, &now)
res := []Info{}
for i := 0; i < m; i++ {
var name string
var lastTime, score int
fmt.Scan(&name, &lastTime, &score)
diff := now - lastTime
lastTestTime := lastTime
grade := getGrade(score)
// 小于0说明复评时间在当前之后
for diff-getInterval(grade) > 0 {
// 更新剩余时间
diff -= getInterval(grade)
// 更新上次剩余时间
lastTestTime += getInterval(grade)
// 更新等级
if grade < 5 {
grade++
}
}
if now-lastTestTime <= 5 {
res = append(res, Info{name, lastTestTime})
}
}
sort.Slice(res, func(i, j int) bool {
if res[i].lastTime == res[j].lastTime {
return res[i].name < res[j].name
}
return res[i].lastTime < res[j].lastTime
})
for i, v := range res {
if i > 0 {
fmt.Print(",")
}
fmt.Print(v.name)
}
}
C语言
cpp
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXN 1000
typedef struct {
char name[505];
int lastTime;
} Info;
// 获取等级
int getGrade(int score) {
if (score <= 19) return 1;
else if (score <= 39) return 2;
else if (score <= 59) return 3;
else if (score <= 79) return 4;
else return 5;
}
// 获取等级评测间隔时间
int getInterval(int grade) {
if (grade == 1) return 36 * 30;
else if (grade == 2) return 12 * 30;
else if (grade == 3) return 8 * 30;
else if (grade == 4) return 6 * 30;
else return 3 * 30;
}
// 排序
int cmp(const void* a, const void* b) {
Info* x = (Info*)a;
Info* y = (Info*)b;
if (x->lastTime == y->lastTime) {
return strcmp(x->name, y->name);
}
return x->lastTime - y->lastTime;
}
int main() {
int m, now;
scanf("%d %d", &m, &now);
Info res[MAXN];
int cnt = 0;
for (int i = 0; i < m; i++) {
char name[505];
int lastTime, score;
scanf("%s %d %d", name, &lastTime, &score);
int diff = now - lastTime;
int lastTestTime = lastTime;
int grade = getGrade(score);
// 小于0说明复评时间在当前之后
while (diff - getInterval(grade) > 0) {
// 更新剩余时间
diff -= getInterval(grade);
// 更新上次评测时间
lastTestTime += getInterval(grade);
// 更新等级
if (grade < 5) grade++;
}
if (now - lastTestTime <= 5) {
strcpy(res[cnt].name, name);
res[cnt].lastTime = lastTestTime;
cnt++;
}
}
qsort(res, cnt, sizeof(Info), cmp);
for (int i = 0; i < cnt; i++) {
if (i > 0) printf(",");
printf("%s", res[i].name);
}
return 0;
}