#P3046. 免单统计(100分)
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 140
            Accepted: 57
            Difficulty: 2
            
          
          
          
                       所属公司 : 
                              华为od
                                
            
                      
          
 
- 
                        算法标签>排序算法          
 
免单统计(100分)
题目描述
华为商城举办了一个促销活动,如果某顾客在某一秒内最早下单的顾客(可能是多个人),则可以获取免单。编程计算有多少顾客可以获取免单。
输入描述
- 整数 
n,表示顾客的数量。 - 接下来的 
n行数据,每一行表示一位顾客的下单时间,以(年-月-日 时-分-秒.毫秒)形式给出。 
输出描述
- 输出一个整数,表示有多少顾客可以获取免单。
 
解题思路
- 时间排序:将所有下单时间进行排序,确保按时间先后排列。
 - 确定免单顾客:
- 遍历排序后的时间列表,记录每一秒的最早下单时间。
 - 对于单位秒里最早的相同时间的订单,都免单。
 
 
复杂度分析
- 时间复杂度:O(n log n),主要体现在排序步骤。
 - 空间复杂度:O(n),用于存储顾客的下单时间。
 
代码实现
C++
#include <bits/stdc++.h>
using namespace std;
int main() {
    int n;
    cin >> n; // 读取顾客数量
    getchar(); // 读取换行符
    vector<string> times(n); // 存储下单时间的字符串数组
    for (int i = 0; i < n; i++) {
        getline(cin, times[i]); // 逐行读取每位顾客的下单时间
    }
    // 按时间排序
    sort(times.begin(), times.end());
    int num = 1; // 免单顾客计数,初始化为1,表示第一个顾客可以免单
    string lastTime = times[0]; // 记录上一个订单的完整时间
    string lastSecond = lastTime.substr(0, 19); // 获取上一个订单的前19个字符(年-月-日 时-分-秒)
    // 遍历从第二个顾客开始的时间
    for (int i = 1; i < n; i++) {
        string curTime = times[i]; // 当前订单的时间
        string curSecond = curTime.substr(0, 19); // 获取当前订单的前19个字符
        // 如果当前订单时间与上一个订单相同,或者当前秒与上一个秒不同
        if (curTime == lastTime || curSecond != lastSecond) {
            num++; // 增加免单顾客计数
            lastTime = curTime; // 更新上一个订单时间
            lastSecond = curSecond; // 更新上一个秒
        }
    }
    cout << num << endl; // 输出免单顾客的数量
    return 0;
}
Java
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt(); // 读取顾客数量
        scanner.nextLine(); // 读取换行符
        String[] times = new String[n]; // 存储下单时间的字符串数组
        for (int i = 0; i < n; i++) {
            times[i] = scanner.nextLine(); // 逐行读取每位顾客的下单时间
        }
        // 按时间排序
        Arrays.sort(times);
        int num = 1; // 免单顾客计数,初始化为1,表示第一个顾客可以免单
        String lastTime = times[0]; // 记录上一个订单的完整时间
        String lastSecond = lastTime.substring(0, 19); // 获取上一个订单的前19个字符(年-月-日 时-分-秒)
        // 遍历从第二个顾客开始的时间
        for (int i = 1; i < n; i++) {
            String curTime = times[i]; // 当前订单的时间
            String curSecond = curTime.substring(0, 19); // 获取当前订单的前19个字符
            // 如果当前订单时间与上一个订单相同,或者当前秒与上一个秒不同
            if (curTime.equals(lastTime) || !curSecond.equals(lastSecond)) {
                num++; // 增加免单顾客计数
                lastTime = curTime; // 更新上一个订单时间
                lastSecond = curSecond; // 更新上一个秒
            }
        }
        System.out.println(num); // 输出免单顾客的数量
    }
}
Python
def main():
    n = int(input())  # 读取顾客数量
    times = [input().strip() for _ in range(n)]  # 存储下单时间的字符串列表
    # 按时间排序
    times.sort()
    num = 1  # 免单顾客计数,初始化为1,表示第一个顾客可以免单
    lastTime = times[0]  # 记录上一个订单的完整时间
    lastSecond = lastTime[:19]  # 获取上一个订单的前19个字符(年-月-日 时-分-秒)
    # 遍历从第二个顾客开始的时间
    for i in range(1, n):
        curTime = times[i]  # 当前订单的时间
        curSecond = curTime[:19]  # 获取当前订单的前19个字符
        # 如果当前订单时间与上一个订单相同,或者当前秒与上一个秒不同
        if curTime == lastTime or curSecond != lastSecond:
            num += 1  # 增加免单顾客计数
            lastTime = curTime  # 更新上一个订单时间
            lastSecond = curSecond  # 更新上一个秒
    print(num)  # 输出免单顾客的数量
if __name__ == "__main__":
    main()
        题目描述
华为商城举办了一个促销活动,如果某顾客是某一秒内最早时刻下单的顾客(可能是多个人),则可以获取免单。
请你编程计算有多少顾客可以获取免单。
输入描述
输入为 n 行数据,每一行表示一位顾客的下单时间以(年-月-日 时-分-秒.毫秒)形式给出。
yyyy-MM-dd HH:mm:ss.fff
0<n<50000
2000<yyyy<2020
0<MM≤12
0<dd≤28
0≤HH≤23
0≤mm≤59
0≤ss≤59
0≤fff≤999
所有输入保证合法
输出描述
输出一个整数,表示有多少顾客可以获取免单。
样例1
输入
3
2019-01-01 00:00:00.001
2019-01-01 00:00:00.002
2019-01-01 00:00:00.003
输出
1
说明
样例 1 中,三个订单都是同一秒内下单,只有第一个订单最早下单,可以免单。
样例2
输入
3
2019-01-01 08:59:00.123
2019-01-01 08:59:00.123
2018-12-28 10:08:00.999
输出
3
说明 样例 2 中,前两个订单是同一秒内同一时刻(也是最早)下单,都可免单,第三个订单是当前秒内唯一一个订单(也是最早),也可免单。
样例3
输入
5
2019-01-01 00:00:00.004
2019-01-01 00:00:00.004
2019-01-01 00:00:01.006
2019-01-01 00:00:01.006
2019-01-01 00:00:01.005
输出
3
说明
样例 3 中,前两个订单是同一秒内同一时刻(也是最早)下单,第三第四个订单不是当前秒内最早下单,不可免单,第五个订单可以免单。