【洛谷刷题 | 第十天】

本系列文章我将总结我在刷算法题所用到的知识,如果你也在刷算法并且是新手,我相信这系列文章会很适合你。

【洛谷刷题 | 第十天】

    • 今日题目:
      • [1. [CSP-J 2021] 网络连接(模拟,字符串,枚举)](#1. [CSP-J 2021] 网络连接(模拟,字符串,枚举))
        • [知识点:sscanf ,sprintf](#知识点:sscanf ,sprintf)
      • [2. [CSP-J 2023] 公路(模拟,贪心,前缀和,反悔贪心)](#2. [CSP-J 2023] 公路(模拟,贪心,前缀和,反悔贪心))

今日题目:

1. [CSP-J 2021] 网络连接(模拟,字符串,枚举)

链接:P7911 [CSP-J 2021] 网络连接

按顺序处理n(n≤1000)台计算机,每台为Server或Client并附带地址串,需验证地址是否符合a.b.c.d:e格式、a/b/c/d为0-255、e为0-65535所有数字均无前导0;Server合法地址不可重复,重复输出FAIL,非法输出ERR,合法唯一输出OK;Client地址非法输出ERR,合法但无对应Server输出FAIL,合法且有对应Server输出其编号。

案例:

cpp 复制代码
输入                                               输出
5                                                 OK
Server 192.168.1.1:8080                           FAIL
Server 192.168.1.1:8080                           1
Client 192.168.1.1:8080                           FAIL
Client 192.168.1.1:80                             ERR
Client 192.168.1.1:99999

首先用map记录已成功建立连接的服务机地址与编号,核心编写地址校验函数:先用sscanf按a.b.c.d:e格式提取 5 个数字,提取失败直接判定非法,再检查数字是否在合法范围(a-d:0-255,e:0-65535),最后用sprintf重新拼接标准地址并与原地址逐字符对比,判断是否存在前导零等非法格式;逐台处理计算机,服务机地址非法输出 ERR,地址已存在输出 FAIL,合法唯一则记录地址并输出 OK,客户机地址非法输出 ERR,能找到对应服务机输出其编号,否则输出 FAIL。

题解:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
map<string,int> mp ;
bool ser(char s1[])
{
    int a = -1,b=-1,c=-1,d=-1,e=-1;
    int t = sscanf(s1,"%d.%d.%d.%d:%d",&a,&b,&c,&d,&e);
    if(t!=5) 
    {
        return 0;
    }
    if(a<0||a>255)   return 0;
    if(b<0||b>255) return 0;
    if(c<0||c>255) return 0;
    if(d<0||d>255) return 0;
    if(e<0||e>65535)  return 0;
    char s2[25];
    sprintf(s2,"%d.%d.%d.%d:%d",a,b,c,d,e);
  
    int len1 = strlen(s1);
    bool ok =1;
    for(int i=0;i<len1;i++)
    {
        if(s1[i]!=s2[i])
        {
            ok = 0;
            break;
        }
    }
    return ok;
}
int main()
{
    int n;
    cin>>n;
    string op;
    char s[109];
    for(int i=0;i<n;i++)
    {
        cin>>op>>s;
       
        if(op=="Server") 
        {
            if(!ser(s)) cout<<"ERR"<<'\n';
            else if(mp.count(s)) 
            cout<<"FAIL"<<'\n';
            else{
                 mp[s] = i+1; cout << "OK\n";
            }
        }
        if(op=="Client")
        {
             if(!ser(s)) cout<<"ERR"<<'\n';
            else if(mp.count(s)) cout<<mp[s]<<'\n';
            else cout<<"FAIL"<<'\n';
        }
       
    }
}
知识点:sscanf ,sprintf

sscanf ,sprintf在【洛谷刷题 | 第八天】已经介绍过,这里做一下小补充。

sscanf

cpp 复制代码
sscanf(s1,"%d.%d.%d.%d:%d",&a,&b,&c,&d,&e);
一次性提取 5 个整数,存入 a、b、c、d、e
返回值 t 的作用:
t == 5 → 成功提取 5 个数,格式合法
t != 5 → 格式错误(少点、少冒号、多符号等)

sprintf

cpp 复制代码
sprintf(s2,"%d.%d.%d.%d:%d",a,b,c,d,e);
把 a、b、c、d、e 按标准格式拼成地址存入 s2,
再和原地址 s1 逐字符比较,不一样就说明有前导零,非法。
sscanf 读取数字时,会自动忽略前导 0
sprintf 写入数字时,也不会自动加前导 0

2. [CSP-J 2023] 公路(模拟,贪心,前缀和,反悔贪心)

链接:P9749 [CSP-J 2023] 公路

从站点 1 开到站点 n,相邻站点距离为 vᵢ,每站油价不同,油箱无限大,每升油能跑 d 公里,初始没油,在每个站只能加整数升油,求走完全程的最少花费。输入的第一行包含两个正整数 n 和 d;输入第二行包含 n-1 个正整数 v₁, v₂ ... vₙ₋₁,分别表示相邻两个站点之间的距离;输入第三行包含 n 个正整数 a₁, a₂ ... aₙ,分别表示每个站点出售汽油的单价。

案例:

cpp 复制代码
输入                                         输出
5 4                                          79
10 10 10 10
9 8 9 6 5

采用贪心算法,从起点开始始终选择当前走过的最便宜油价加油,依次行驶到每个站点,累加需要行驶的总路程,每次用向上取整算出需要加的油量,乘以当前最低油价计入总花费,同时扣除已消耗的油量,持续到终点,最终得到最小油费。

题解:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int a[100009];
int b[100009];
long long ans = 0;
int sum = 0;
int main()
{
    int n,d;
    cin>>n>>d;
    for(int i=0;i<n-1;i++)
    {
        cin>>a[i];
    }
    for(int i=0;i<n;i++)
    {
        cin>>b[i];
    }
    int c= b[0];
    int t=0;
    for(int i=0;i<n-1;i++)
    {
        sum+=a[i];
        c= min(c,b[i]);
        if(sum>0){
            ans+=(sum+d-1)/d*c;
            sum-=(sum+d-1)/d*d;
     }
        }
    cout<<ans;
}         

最后:

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力!

相关推荐
Mr_Xuhhh2 小时前
LeetCode 热题 100 刷题笔记:数组与排列的经典解法
数据结构·算法·leetcode
老四啊laosi2 小时前
[双指针] 3. 力扣--快乐数
算法·leetcode·快慢指针
rit84324992 小时前
利用随机有限集(RFS)理论结合ILQR和MPC控制蜂群的MATLAB实现
算法·matlab
会编程的土豆2 小时前
leetcode hot 100 之哈希
算法·leetcode·哈希算法
秋天的一阵风2 小时前
【LeetCode 刷题系列|第 3 篇】详解大数相加:从模拟竖式到简洁写法的优化之路🔢
前端·算法·面试
qwehjk20082 小时前
分布式计算C++库
开发语言·c++·算法
m0_716765232 小时前
C++提高编程--仿函数、常用遍历算法(for_each、transform)详解
java·开发语言·c++·经验分享·算法·青少年编程·visual studio
寻寻觅觅☆2 小时前
东华OJ-基础题-59-倒数数列(C++)
开发语言·c++·算法
我不是懒洋洋2 小时前
【数据结构】顺序表专题(详细代码及配图)
c语言·开发语言·数据结构·算法·青少年编程·visual studio