HNUCM-2023年春季学期《算法分析与设计》练习1

记录下自己的学习记录。


问题A:X星人的地盘

用python调试几次都没过,后来改成多组输入捕获异常就可以了(自己编译器可以过oj过不了可能是输入输出的原因)


题目描述:

一天,X星人和Y星人在一张矩形地图上玩抢地盘的游戏。
X星人每抢到一块地,在地图对应的位置标记一个“X”;Y星人每抢到一块地,在地图对应的位置标记一个“Y”;如果某一块地无法确定其归属则标记一个“N”。
最终统计谁拥有的地盘最大,即统计“X”和“Y”的个数。如果“X”的个数多,则说明X星人的地盘更大,输出“X
win”;反之,如果Y星人的地盘更大,则输出“Y win”;如果X星人和Y星人拥有的地盘一样大,则输出“The same”。

输入

单组输入。 第1行输入两个正整数m和n,表示地图矩阵的行和列。(m和n均不超过1000)
从第2行到第m+1行,输入一个由’X’、'Y’和’N’三种字符组成的矩阵,每行包含n个字符,一共m行。

输出

如果X星人拥有的地盘大,输出“X win”;如果Y星人拥有的地盘大,输出“Y win”;如果拥有的地盘一样大,输出“The same”。

a, b = 0, 0
while True:
    try:
        s = input()
        if s == '':
            break
        a += s.count('X')
        b += s.count('Y')
    except:
        break
if a == b:
    print('The same')
elif a > b:
    print('X win')
else:
    print('Y win')

问题B:x星宿舍

简单的模拟题


题目描述:

X星大学的宿舍很有意思,男生都是6人间,女生都是5人间。
现在已知N个学生的性别,性别用’0’或者’1’表示,其中’0’表示男生,'1’表示女生。
请你编写一个程序计算最少需要多少间男生宿舍?多少间女生宿舍? (注:不要求每一间宿舍都住满)。

输入

单组输入。 输入N个0或1,两两之间用英文空格隔开,且N不超过1000。

输出

输出两个整数,分别表示最少需要的男生宿舍和女生宿舍数量,两者之间用英文空格隔开。

a = list(map(int, input().split()))
x = a.count(0)
y = a.count(1)
if x % 6 == 0:
    print(x // 6, end=' ')
else:
    print(x // 6 + 1, end=' ')
if y % 5 == 0:
    print(y // 5)
else:
    print(y // 5 + 1)

问题C:一二三

一直是50%不知道为什么(同样的方法C++可以),后来发现样例输入有空格,用了去空格函数还是不可以。
思路很简单,枚举一下就可以。


题目描述

你弟弟刚刚学会写英语的一(one)、二(two)和三(three)。他在纸上写了好些一二三,可惜有些字母写错
了。已知每个单词最多有一个字母写错了(单词长度肯定不会错),你能认出他写的啥吗?

输入

第一行为单词的个数(不超过 10)。以下每行为一个单词,单词长度正确,且最多有一个字母写错。所有 字母都是小写的。

输出

对于每组测试数据,输出一行,即该单词的阿拉伯数字。输入保证只有一种理解方式。

def check(s):
   if len(s) == 5:
       return 3
   else:
       if (s[0] == 't' and s[1] == 'w') or (s[0] == 't' and s[2] == 'o') or (s[1] == 'w' and s[2] == '0'):
           return 2
       else:
           return 1


t = int(input())
num = [input().strip() for i in range(t)]   #  strip()函数去掉字符串前面和后面的空格
for word in num:
   print(check(word))

#include<iostream>
#include<string.h>
using namespace std;
int main()
{
    
    
   char c[10];
   int n;
   while(cin>>n)
   {
    
    
       for(int i=0;i<n;i++)
       {
    
    
           cin>>c;
           if(strlen(c)==5)
               cout<<3<<endl;
           else
           {
    
    
 
                   if((c[0]=='o'&&c[1]=='n')||(c[0]=='o'&&c[2]=='e')||(c[1]=='n'&&c[2]=='e'))
                       cout<<1<<endl;
                   else
                       cout<<2<<endl;
           }
       }
   }
   return 0;
}

问题D:三家人

思路:先求出ABC三个太太每个人应该打扫的的平均天数,A太太应得的金额就是A太太帮忙C太太打扫的天数占C太太应打扫天数的百分比乘以C太太出的钱。
题目描述

有三户人家共拥有一作花园,每户人家的太太均需帮忙整理花园。A太太工作了 5天,B太太则工作了 4天,才将花园整理完毕。C
太太因为正身怀六甲无法加入她们的行列,便出了 90 元。请问这笔钱如何分给 A、B二位太太较为恰当?A应得多少元?
90/(5+4)*5=50元?如果这么想你就上当了!正确答案是 60元。如果没想通的话再想想吧。 下面回答一个一般性的问题:假定 A
太太工作了 x 天,B 太太工作了 y 天,C 太太出了 90 元,则 A太太应得多少元?输入保证二位太太均应得到非负整数元钱。

输入

输入第一行为数据组数T( T <=20)。每组数据仅一行,包含三个整数x ,y ,z(1<= x ,y <=10,1<= z
<=1000)。

输出

对于每组数据,输出一个整数,即 A太太应得的金额(单位:元)。

T = int(input())
for _ in range(T):
    a, b, c = map(float, input().split())
    average = (a+b) / 3  # 平均天数
    a1 = a - average  # A太太多做的天数
    s = a1/average*c
    print(int(s))


问题E:汽水瓶

看代码注解就好。


题目描述

有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?

输入

输入文件最多包含10组测试数据,每个数据占一行,仅包含一个正整数n(1<=n<=100),表示小张手上的空汽水瓶数。n=0表示输入结束,你的程序不应当处理这一行。

输出

对于每组测试数据,输出一行,表示最多可以喝的汽水瓶数。如果一瓶也喝不到,输出0。

while True:
    try:
        n = int(input())
        if n == 0:
            break
        s = 0  # 最终兑换数量
        i = 0  # 兑换而来的汽水数量
        while n:
            if n == 1:
                break
            elif n == 2:
                s += 1
                break
            else:
                i = n // 3
                s += i
                n = n % 3 + i  # 兑换之后剩余的空瓶子
        print(s)
    except:
        break

问题F:数字整除

由于python语言的特性,所以是可以直接处理大数运算的。


题目描述

定理:把一个至少两位的正整数的个位数字去掉,再从余下的数中减去个位数的5倍。当且仅当差是17的倍数时,原数也是17的倍数 。

例如,34是17的倍数,因为3-20=-17是17的倍数;201不是17的倍数,因为20-5=15不是17的倍数。输入   一个正整数n,你的任务是判断它是否是17的倍数。

输入

输入文件最多包含10组测试数据,每个数据占一行,仅包含一个正整数n(1<=n<=10的100次方),表示待判断的正整数。n=0表示输入结束,你的程序不应当处理这一行。

输出

对于每组测试数据,输出一行,表示相应的n是否是17的倍数。1表示是,0表示否。

while True:
    n = int(input())
    if n == 0:
        break
    if n % 17 == 0:
        print(1)
    else:
        print(0)

问题G:超大型LED显示屏

思路:用一个字典来储存每一个数字所代表的单位耗电量,然后写一个time函数来计算两个时间段的秒数,再写一个check函数来计算总耗电量,就是模拟,看代码就懂了。注意两个边界情况,一个是刚开始比赛和第一次得分,一个是最后一次得分和比赛结束的时间点,要特殊处理一下。


题目描述

你是学生会体育部长,负责组织一年一度的校篮球比赛。马上就要决赛了,你希望吸引更多的 人来看比赛,因此打算更新一下设备,用一个超大的
LED屏幕来显示比分。当然,电也不是 不要钱的,所以你决定先分析一下往年的比赛,估计一下大概要耗多少电。 如上图,每个数字由
7条线段组成,每条亮着的线段每秒钟耗电量为 1个单位。线段不亮的时 候不耗电。为了省电,比分不显示前导 0(不过 0分的时候要显示数字
0)。 你的 LED显示屏共包含 6个数字,即双方的比分各有 3 位数。

比分表

输入

输入包含不超过 100组数据。每组数据第一行为"START hh:mm:ss",表示比赛开始时刻为 hh:mm:ss。最后一行为"END
hh:mm:ss",即比赛结束时刻。二者之间至少会有一个 SCORE信 息,格式为"SCORE hh:mm:ss team
score",其中 team要么是"home"(主场)要么是"guest"(客 场), score表示得分,为 1,2或者
3。这些信息保证按照时间从早到晚的顺序排列,且任意两 条 SCORE信息的时刻均不相同。比赛开始时间不会早于
9:00,结束时间不会晚于同一天的 21:00。注意,如果比赛开始时间为 09:00:00,结束时间为 09:00:01,比赛长度为
1秒钟,而不 是 2秒钟。

输出

对于每组数据,输出测试点编号和总耗电量。

dist = {
    
    '0': 6,
        '1': 2,
        '2': 5,
        '3': 5,
        '4': 4,
        '5': 5,
        '6': 6,
        '7': 3,
        '8': 7,
        '9': 6}
def time(s1, s2):
    res1 = s1[1].split(':')
    res2 = s2[1].split(':')
    sec = 0
    sec += (int(res2[0]) - int(res1[0])) * 3600
    sec += (int(res2[1]) - int(res1[1])) * 60
    sec += (int(res2[2]) - int(res1[2]))
    return sec
def check(num):
    home, guest = 0, 0  # 得分
    res = 0  # 答案
    s = time(num[0], num[1])  # 秒数
    res += 2*(dist['0']*s)  # 开始和第一次得分
    for i in range(1, len(num)):
        if i + 1 == len(num) - 1:  # 最后一次得分和比赛结束
            s = time(num[i], num[i + 1])
            x, y = 0, 0
            for i in str(home):
                x += dist[i]
            for i in str(guest):
                y += dist[i]
            res += (x+y) * s
            break
        else:
            s = time(num[i], num[i + 1])
            x, y = 0, 0
            if num[i][2] == 'home':
                home += int(num[i][3])
                for i in str(home):
                    x += dist[i]
                for i in str(guest):
                    y += dist[i]
                res += (x+y) * s
            else:
                guest += int(num[i][3])
                for i in str(home):
                    x += dist[i]
                for i in str(guest):
                    y += dist[i]
                res += (x+y) * s
    return res
count = 0
while True:
    try:
        count += 1
        a = []
        while True:
            s = input().split(' ')
            if s[0] == 'END':
                a.append(s)
                break
            else:
                a.append(s)
        a.append(s)  # 防止列表越界,对结果并没有影响
        print(f'Case {
      
      count}: {
      
      check(a)}')
    except:
        break

问题H:聊天止于呵呵

思路:用一个字典来存储两个人对话的最后一段话(如何确定说话的两个人代码中有体现),然后按照题目要求写一个函数来改变对话,写一个函数来检查对话是否合格。


题目描述

(现代版)俗话说:流言止于智者,聊天止于呵呵。输入一段聊天记录,你的任务是数一数有 多少段对话“止于呵呵”,即对话的最后一句话包含单词
hehe或者它的变形。 具体来说,我们首先提取出对话的最后一句话,把所有非字母的字符替换成空格,把所有字符
替换成小写,然后导出一个单词列表(由空格隔开),只要列表中的任何一个单词是 hehe,这 段对话就算作“止于呵呵”。比如,“Hi! Are
you OK?” 会变成四个单词:hi, are, you, ok。注 意,单词列表可以是空的(比如,这句话是:“?!?!!”)
有些人喜欢使用 hehe的变形,这些变形也应被视为“呵呵”。为了简单起见,本题只考虑由 n(n>1)个 he连接而成的单词,比如
hehehe或者 hehehehe。注意,以 hehe为连续子串的其他单 词不应视为“呵呵”,比如 hehee,或者 ehehe。
每两个不同人之间的所有对话算作“一段对话”。

输入

输入仅包含一组数据,每行是一句对话,格式为:

人名 1->人名 2: 一句话.

每行最多包含 1000个字符,最多 100行。

输出

输出“止于呵呵”的对话段落所占的百分比,四舍五入到最近的整数。输入数据保证答案不会 同时和两个整数最近。

dist = {
    
    }
def check(s):
   if len(s) % 2 != 0:
       return False
   for i in range(0, len(s), 2):
       new_s = s[i:i + 2:]
       if new_s != 'he':
           return False
   return True
def f(s):
   new_word = ''
   s = s.lower()
   for i in range(len(s)):
       if not s[i].isalpha():
           new_word += ' '
       else:
           new_word += s[i]
   return new_word.split()
while True:
   try:
       people, word = input().split(': ')
       s = people.split('->')
       if s[0] > s[1]:
           s[0], s[1] = s[1], s[0]
       t = ''.join(s)
       if t not in dist:
           dist[t] = f(word)
       else:
           dist[t] = f(word)
   except:
       # print(dist)
       count = 0
       sum_word = len(dist)
       for word in dist.values():
           for words in word:
               if check(words) and len(words) >= 4:
                   count += 1
       res = count * 100 / sum_word
       print("%.f" % res + '%')
       break

总结

题目没有什么算法,都是一些思维题和根据题意模拟。

猜你喜欢

转载自blog.csdn.net/weixin_62988040/article/details/129323700