【题解】ABC001题解

AtCoder Beginner Contest 001 题解

目录

  1. A - 积雪深差
  2. B - 视程の通報
  3. C - 風力観測
  4. D - 感雨時刻の整理

A - 积雪深差

问题描述

给定两个整数H1和H2,分别表示第一天和第二天的积雪深度,计算并输出它们的差值。

输入

两个整数H1和H2,每个整数占一行。

输出

H1 - H2的结果。

解题思路

这是一个非常简单的题目,只需要读取两个整数并输出它们的差值即可。

代码实现

#include<bits/stdc++.h>
using namespace std;

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int a, b;
    cin >> a >> b;
    cout << a - b << '\n';
    return 0;
}

复杂度分析

  • 时间复杂度:O(1)
  • 空间复杂度:O(1)

B - 视程の通報

问题描述

根据给定的可视距离(米),按照特定规则转换为VV值并输出。

转换规则

  • 小于100米:VV=00
  • 100-5000米:VV=米数/100(不足两位前面补零)
  • 6000-30000米:VV=米数/1000+50
  • 35000-70000米:VV=(米数/1000-30)/5+80
  • 超过70000米:VV=89

输入

一个整数m表示可视距离(米)。

输出

转换后的VV值。

解题思路

根据题目给出的条件,使用if-else语句进行判断并计算对应的VV值即可。

代码实现

#include<bits/stdc++.h>
using namespace std;

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int m;
    cin >> m;
  
    if(m < 100) {
        cout << "00\n";
    }
    else if(m <= 5000) {
        if(m >= 1000) cout << m/100 << '\n';
        else cout << '0' << m/100 << '\n';
    }
    else if(m <= 30000) {
        cout << m/1000 + 50 << '\n';
    }
    else if(m <= 70000) {
        cout << ((m/1000)-30)/5 + 80 << '\n';
    }
    else {
        cout << "89\n";
    }
  
    return 0;
}

复杂度分析

  • 时间复杂度:O(1)
  • 空间复杂度:O(1)

C - 風力観測

问题描述

根据给定的风向角度和风速,计算并输出风向(16方位)和风力等级。

输入

两个浮点数deg和dis,分别表示风向角度(0-3600,实际角度=deg/10)和风速(米/秒)。

输出

风向和风力等级,用空格分隔。

解题思路

  1. 风向计算:将角度转换为16方位
  2. 风速计算:将风速转换为风力等级(0-12级)

代码实现

#include<bits/stdc++.h>
using namespace std;

int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    double deg, dis;
    cin >> deg >> dis;
  
    // 处理风向
    deg /= 10;
    int ran = 0;
    double min = 11.25, max = 33.75;
    string s[17] = {"N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW","C"};
  
    for(int i = 1; i <= 15; i++) {
        if(min <= deg && deg < max) ran = i;
        min += 22.5; max += 22.5;
    }
  
    // 处理风速
    dis = round((dis / 60.0) * 10.0) / 10;
    int wp = 0;
  
    if(0.0 <= dis && dis <= 0.2) ran = 16;
    if(0.3 <= dis && dis <= 1.5) wp = 1;
    if(1.6 <= dis && dis <= 3.3) wp = 2;
    if(3.4 <= dis && dis <= 5.4) wp = 3;
    if(5.5 <= dis && dis <= 7.9) wp = 4;
    if(8.0 <= dis && dis <= 10.7) wp = 5;
    if(10.8 <= dis && dis <= 13.8) wp = 6;
    if(13.9 <= dis && dis <= 17.1) wp = 7;
    if(17.2 <= dis && dis <= 20.7) wp = 8;
    if(20.8 <= dis && dis <= 24.4) wp = 9;
    if(24.5 <= dis && dis <= 28.4) wp = 10;
    if(28.5 <= dis && dis <= 32.6) wp = 11;
    if(32.7 <= dis) wp = 12;
  
    cout << s[ran] << ' ' << wp << '\n';
    return 0;
}

复杂度分析

  • 时间复杂度:O(1)
  • 空间复杂度:O(1)

D - 感雨時刻の整理

问题描述

给定多个降雨时间段(格式为HHMM-HHMM),将这些时间段合并并输出。

合并规则

  1. 将每个时间段的开始时间向下取整到最近的5分钟倍数
  2. 将结束时间向上取整到最近的5分钟倍数
  3. 合并重叠或相邻的时间段

输入

第一行是整数n,表示时间段数量。接下来n行每行是一个时间段(HHMM-HHMM)。

输出

合并后的时间段列表,每行一个时间段,按开始时间排序。

解题思路

  1. 处理每个时间段:调整开始和结束时间
  2. 排序所有时间段
  3. 合并重叠或相邻的时间段
  4. 输出结果

代码实现

#include<bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    cin >> n;
    vector<pair<int, int>> vii;
  
    for(int i = 1; i <= n; i++) {
        int num1, num2;
        scanf("%d-%d", &num1, &num2);
        num1 = num1 / 5 * 5;
        num2 = (num2 + 4) / 5 * 5;
        if(num2 % 100 == 60) num2 += 40;
        vii.push_back({num1, num2});
    }
  
    sort(vii.begin(), vii.end());
    vector<pair<int, int>> ans;
    ans.push_back(vii[0]);
  
    for(auto i = vii.begin(); i != vii.end(); i++) {
        if(i->first <= ans.back().second) {
            ans.back().second = max(ans.back().second, i->second);
        }
        else {
            ans.push_back(*i);
        }
    }
  
    for(auto &i : ans) {
        printf("%04d-%04d\n", i.first, i.second);
    }
  
    return 0;
}

复杂度分析

  • 时间复杂度:O(n log n) (主要来自排序)
  • 空间复杂度:O(n)
posted @ 2025-05-31 14:58  这很调和  阅读(54)  评论(0)    收藏  举报