CSDN编程题-每日一练(2023-08-25)

CSDN编程题-每日一练(2023-08-25)

  • 一、题目名称:影分身
  • 二、题目名称:小鱼的航程(改进版)
  • 三、题目名称:排查网络故障

一、题目名称:影分身

时间限制:1000ms内存限制:256M

题目描述:

已知字符串str。字符串str包含字符’x’,’y’。 如果相邻的两个字符不同,消除两个字符,优先从左边进行消除。 xyyx - > yx ->

输入描述:

输入多个字符。(1<=len<=1e5)

输出描述:

输出最后的分身

示例:

✔️ 示例1:

输入
xyyyy

输出
yyy

解题思路:

根据题目描述,我们需要对输入的字符串进行处理,消除相邻的不同字符。优先从左边开始消除。可以使用栈(Stack)数据结构来实现。

代码1如下:

s = input().strip()  # 输入字符串

##函数 calc 接受一个字符串参数 s,返回一个字符串作为最后的分身
def calc(s: str) -> str:
    stack = []  # 初始化一个空栈 stack,用于存储字符

    for ch in s:  # 遍历输入的字符串s,依次处理每个字符
        if not stack or ch == stack[-1]:  # 栈为空(not stack)或者当前字符 ch 与栈顶字符相同 (ch == stack[-1])
        ##将当前字符 ch 入栈 (stack.append(ch))
            stack.append(ch)
        else:  
      ##  如果栈不为空,并且当前字符 ch 与栈顶字符不同,说明找到了一对相邻不同的字符,将栈顶字符出栈 (stack.pop())
            stack.pop()

##遍历完整个字符串后,栈中剩余的字符即为最后的分身
##使用 join 函数将栈中的字符按照出栈顺序组合起来,返回结果
    return ''.join(stack) 

result = calc(s)  # 消除相邻的不同字符
print(result)  # 输出最后的分身

CSDN编程题-每日一练(2023-08-25)_第1张图片

代码2如下:

#include 
#include 
#include 

##定义一个名为 calc的函数,接受一个常量引用字符串作为参数,并返回一个字符串。
std::string calc(const std::string& s) {
    std::stack<char> stack; #声明一个字符栈 stack,用于模拟栈结构

#使用 for 循环遍历输入字符串 s,依次处理每个字符
    for (char ch : s) {
    ##对于每个字符 ch 进行判断:
##1、如果栈为空(stack.empty())或者当前字符 ch 与栈顶字符相同(ch == stack.top()),将当前字符 ch 入栈(stack.push(ch))。
##2、如果栈不为空,并且当前字符 ch 与栈顶字符不同,说明找到了一对相邻不同的字符,将栈顶元素出栈(stack.pop())
        if (stack.empty() || ch == stack.top()) {
            stack.push(ch);
        } else {
            stack.pop();
        }
    }

##使用 for 循环遍历输入字符串 s 中的每个字符 ch。对于每个字符,如果栈为空或者当前字符与栈顶字符相同,将当前字符入栈;否则,说明找到了一对相邻不同的字符,将栈顶元素出栈
    std::string result; #创建一个空字符串 result,用于保存最后的分身
    while (!stack.empty()) {  ##使用 while 循环将栈中的字符依次出栈,并将出栈的字符加到 result 的前面
        result = stack.top() + result;
        stack.pop();
    }

##最后返回保存最后的分身的字符串 result
    return result;
}

int main() {
    ##声明一个字符串 s,用于存储输入的字符串
    std::string s;
    ##使用 std::getline 函数从标准输入中获取一行字符串
    std::getline(std::cin, s);

    ##调用 calc函数处理输入字符串,得到最后的分身,将其赋给字符串变量 result
    std::string result = calc(s);
    ##使用 std::cout 将结果输出到标准输出流,并在末尾添加换行符
    std::cout << result << std::endl;
    ##程序正常结束
    return 0;
}

CSDN编程题-每日一练(2023-08-25)_第2张图片

二、题目名称:小鱼的航程(改进版)

时间限制:1000ms内存限制:256M

题目描述:

有一只小鱼,它上午游泳150公里,下午游泳100公里,晚上和周末都休息(实行双休日),假设从周x(1<=x<=7)开始算起,请问这样过了n天以后,小鱼一共累计游泳了多少公里呢?

输入描述:

输入两个整数x,n(表示从周x算起,经过n天,n在long int范围内)。

输出描述:

输出一个整数,表示小鱼累计游泳了多少公里。

示例:

✔️示例1
输入

3 10

输出
2000

解题思路:

根据输入的起始天数x和总天数n,计算一定天数内(包括起始天数)游泳的总公里数。

代码1如下:

# 读取输入,起始天数x和经过的天数n
x, n = map(int, input().split())

def solution(x, n):

#计算出从起始天数开始经过n天后的总天数total_days :total_days = n + x - 1
    total_days = n + x - 1
    #计算完整周期(一周)的游泳公里数total_km
    total_km = total_days // 7 * 250 * 5
    
    ##计算额外的天数excess_days ,即不足一周的天数
    excess_days = total_days % 7
    ##循环遍历range(excess_days)来判断每一天是否是工作日(小于5),如果是则将游泳公里数增加250米
    for i in range(excess_days):
        if i < 5:
            total_km += 250
##循环遍历从周一到前一天(range(1, x))的天数,在工作日(小于6)中减去250米的游泳公里数
    for i in range(1, x):
        if i < 6:
            total_km -= 250
            
    ###计算得到的游泳公里数total_km作为函数的返回值
    return total_km
    
###调用solution(x, n)
total_km=solution(x, n)
print(total_km)

CSDN编程题-每日一练(2023-08-25)_第3张图片

代码2如下:

#include 
#include 

#define MAX_SIZE 100

## 注意:n在long int范围内
long int solution(long int x, long int n) {
    long int total_days = n + x - 1;
    long int total_km = total_days / 7 * 250 * 5;
    
    long int excess_days = total_days % 7;
    for (long int i = 0; i < excess_days; i++) {
        if (i < 5) {
            total_km += 250;
        }
    }

    for (long int i = 1; i < x; i++) {
        if (i < 6) {
            total_km -= 250;
        }
    }

    return total_km;
}

int main() {
    long int x, n;
    scanf("%ld %ld", &x, &n);

    long int total_km = solution(x, n);
    printf("%ld\n", total_km);

    return 0;
}

CSDN编程题-每日一练(2023-08-25)_第4张图片

三、题目名称:排查网络故障

时间限制:1000ms内存限制:256M

题目描述:

A地跟B地的网络中间有n个节点(不包括A地和B地),相邻的两个节点是通过网线连接。正常的情况下,A地和B地是可以连通的,有一天,A地和B地突然不连通了,已知只有一段网线出问题(两个相邻的节点)小明需要排查哪段网线出问题。他的排查步骤是: 1。 选择某个中间节点 2。 在这个节点上判断跟A地B地是否连通,用来判断那一边出问题 请问小明最少要排查多少次,才能保证一定可以找到故障网线。

输入描述:

一个正整数 n (n <= 10^18),表示A地和B地之间的节点数。

输出描述:

输出一个数字,代表保证一定可以找到故障网线的前提下,小明最少要排查多少次?

示例:

✔️示例1
输入
2

输出
2

解题思路:

假设节点数为n,我们可以将整个网络划分为两半,即左边的节点和右边的节点。如果某个节点被选为判断节点,那么它所在的位置就决定了是哪一半出了问题。

对于一个给定的节点数n,首先找到最接近n的2的幂次方m,使得m <= n。然后,排查的次数就是最接近n的2的幂次方的对数log2(m)。

首先观察题目中的连接方式,可以发现节点数n与排查次数node_number之间存在一定的关系。

1、假设排查次数为x,那么排查的节点个数应为2^x - 1。
2、当排查的节点个数超过了n时,即2^x - 1 > n,说明排查次数为x-1时已经可以确定故障网线的位置。
3、根据以上思路,可以用循环不断将n除以2,直到n小于等于0为止,每次循环时check_number 加1。
4、最后输出check_number 即为所求的最少排查次数。

代码1如下:*

##A地和B地之间的节点数n
n = int(input())
##计数器check_number , 排查次数
check_number = 0
##当n大于0时,执行循环体
while n > 0:
##将n除以2,结果赋值给n,相当于将节点数减半,直到n小于等于0为止
    n = n // 2
###每次循环时,将check_number 加1
    check_number += 1
###输出check_number即为所求的最少排查次数
print(check_number)

CSDN编程题-每日一练(2023-08-25)_第5张图片

代码2如下:*

解题思路:

首先,我们需要找到一个节点,通过判断这个节点是否与A地和B地连通,来确定故障网线是在节点的哪一边。

假设A地和B地之间有n个节点,我们可以将节点数n表示成二进制形式。例如,n=2时,二进制为10,表示有两个节点。

我们观察一下,当节点数为2的幂次方时,排查次数最少。例如,n=2时,只有节点2需要排查;n=4时,只有节点4需要排查;n=8时,只有节点8需要排查,以此类推。

因此,我们可以先找到节点数n的二进制表示中最高位的1的位置,记为highest_bit_pos。然后,我们构造一个掩码mask,将最高位1右边的所有位都置为1。再将节点数n与掩码mask进行或运算,得到masked_n。

最后,我们统计masked_n中1的个数,即为小明最少要排查的次数。

n = int(input())

# 1、找到最高位1的位置,即二进制字符串的长度减去3,
###  如: bin(2)的结果是字符串'0b10'。长度为4,这表示二进制数2的二进制表示形式为10。前缀0b表示这是一个二进制数,最高位为1
highest_bit_pos = len(bin(n)) - 3

# 2、将最高位1右边的所有位都置为1
##使用左移运算符<<将1左移highest_bit_pos个位数,然后减去1,生成一个二进制数,其中最高位1的右边都是1,其余位为0。这个二进制数被赋值给变量mask
mask = (1 << highest_bit_pos) - 1

##3、按位或运算符|将n与mask进行按位或操作
###将masked_n的最高位1右边的所有位都置为1,而其余位与n保持相同
masked_n = n | mask

# 4、计算1的个数
##将masked_n转换为二进制字符串,然后使用count()函数计算其中字符'1'的个数
count = bin(masked_n).count('1')

#5、输出count,即masked_n中1的个数
print(count)

示例输入解释:

例如,当输入为2时,输出为2。解释:

1、节点数n为2,二进制表示为10。
2、找到最高位1的位置为1,即highest_bit_pos=1。
3、构造掩码mask,将最高位1右边的所有位都置为1,即mask=1。
4、将节点数n与掩码mask进行或运算,得到masked_n=3。
5、统计masked_n中1的个数,即为小明最少要排查的次数,即count=2。

CSDN编程题-每日一练(2023-08-25)_第6张图片

你可能感兴趣的:(csdn编程题-每日一练,编程语言,python,算法,字符串,数学,栈,数据结构,影分身,小鱼的航程-改进版,排查网络故障)