RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 887994
Accepted
Ole Lukøje
Ole Lukøje
Asked:2020-10-02 06:49:45 +0000 UTC2020-10-02 06:49:45 +0000 UTC 2020-10-02 06:49:45 +0000 UTC

关于电话号码的问题

  • 772

站点验证系统不做决定,请告诉我错误在哪里。

实际任务:

1002. 电话号码

时间限制:2.0 秒
内存限制:64 MB

在当今世界,您面临着大量的电话号码,这些电话号码随着时间的推移越来越长。你必须记住这些数字。一种容易记住的方法是将字母与每个数字匹配,如下图所示:

1 ij    2 abc   3 def
4 gh    5 kl    6 mn
7 prs   8 tuv   9 wxy
        0 oqz

通过这种方式,可以为每个单词或单词组分配一个唯一的编号,以便记住单词而不是电话号码。显然,在用于记住电话号码的单词和该号码的所有者之间找到简单的关系具有特殊的魅力。因此,您下棋的朋友的电话号码 941837296 可以读作 WHITEPAWN(白兵),而您最喜欢的老师的电话号码 2855304 可以读作 BULLDOG(斗牛犬)。

编写一个程序,找到与给定电话号码和给定单词列表匹配的最短单词序列(具有最少单词)。对应关系如上图所示。

初始数据

输入由一组测试组成。每个测试的第一行包含您要匹配助记符的电话号码。该号码由不超过 100 位数字组成。第二行包含字典中的单词总数(最多 50,000 个)。剩下的每一行都包含一个单词,由不超过 50 个小写拉丁字母组成。总输入大小不超过 300 KB。最后一个输入行包含数字 -1。

结果

每行输出必须包含程序找到的最短单词序列。单词必须用单个空格分隔。如果输入没有解决方案,则相应的输出行应包含 text No solution.。如果有多个单词数相同的解决方案,您可以选择其中任何一个。


作者的输入和输出数据,例如:

7325189087
5
it
your
reality
real
our
4294967296
5
it
your
reality
real
our
-1
# Ожидаемый результат  
reality our
No solution.

我的测试输入:

2272583262772
11
ba
ra
ku
k
ss
u
ma
da
m
a
ssa
-1

从逻辑上讲,答案应该是

ba ra ku da ma ssa

但由于某种原因,此解决方案不在可能的解决方案列表中。
如果你把它放在ma之后,da那么这个解决方案就找到了。
以下是从中做出最佳选择的解决方案列表:

['ba', 'ra', 'ku', 'da', 'm', 'a', 'ss', 'a']
['a', 'a', 'ra', 'ku', 'da', 'm', 'a', 'ss', 'a']

因此,最佳代码考虑:

ba ra ku da m a ss a

好吧,因此验证者不接受这个决定。
请告诉我错误在哪里

我的决定:

keyboard = {'1': 'ij', '2': 'abc', '3': 'def',
            '4': 'gh', '5': 'kl', '6': 'mn',
            '7': 'prs', '8': 'tuv', '9': 'wxy',
            '0': 'oqz'}

while True:
    phone_num = input()
    solutions = []
    if phone_num == '-1':
        break
    phone_len = len(phone_num)
    words = [input() for _ in range(int(input()))]
    collector = []
    for word in words:
        if len(word) > phone_len:
            continue

        solution = []
        for i in range(len(word)):
            if word[i] not in keyboard[phone_num[i]]:
                break

        else:
            solution.append(word)
            test_solution = []

            while test_solution != solution:
                test_solution = solution.copy()
                raw_solution = ''.join(solution)
                len_solution = len(raw_solution)
                new_words = [item for item in words if len(item) <= phone_len - len_solution]
                if new_words:
                    for item in new_words:
                        raw_solution = ''.join(solution)
                        len_solution = len(raw_solution)
                        test_string = raw_solution + item
                        len_test_string = len(test_string)
                        if len_test_string > phone_len:
                            continue
                        for s in range(len_solution, len_test_string):
                            if test_string[s] not in keyboard[phone_num[s]]:
                                break
                        else:
                            solution.append(item)

            solutions.append(solution)

    if solutions:
        solutions.sort(key=lambda g: len(g))
        print(*solutions[0])
    else:
        print('No solution.')
python
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    KosWarm
    2020-10-10T01:04:50Z2020-10-10T01:04:50Z

    通用解法原理:

    令 N 为电话号码的长度。

    我们将字典表示为 M 个单词的列表。

    所有字典单词都可以立即重写为数字序列。

    然后我们创建一个维度为 N+1 x N+1 的方阵(我假设所有地方的索引都从 0 开始)。

    矩阵的每个单元格 (i,j) = k 意味着我们有一个字典中编号为 k 的单词,它与电话数字的 i .. j-1 部分匹配。

    用值 -1 填充其所有单元格。这将意味着我们没有这样的词。

    然后,在所有单词的循环中,我们检查它们适合电话号码的哪一部分并填写矩阵。

    然后,广度优先搜索在我们的矩阵中找到从 0 到 N 的路径。

    如果找到路径,则路径的单元格值下的字典中的单词将是问题的解决方案,否则“无解决方案”。

    矩阵填充时间 O(NxM)。广度优先搜索时间 O(NxN)。

    不是最好的方法:

    n = len(phone_num)
    m = int(input())
    words = [input() for _ in range(m)]
    
    # Создаём матрицу (n+1) x (n+1)
    a = [[-1] * (n+1) for i in range(n+1)]
    
    
    wordNumbers = [convertToNumber(words[i]) for i in range(m)]
    
    # Заполняем матрицу переходов
    # перебираем слова и проверяем, что они совпадают с частью номера телефона
    for i in range(n):
        for k in range(m):
            number = wordNumbers[k]
            number_length = len(number)
    
            if (phone_num[i:i+number_length] == number):
                a[i][i+number_length]=k
    
    
    #Поиск в ширину
    
    # Сюда будем записывать вершины пути 
    # (вес, откуда пришли, куда идём)
    # По вершине на каждую цифру номера
    vertex = [(10000000,-1,-1)] * (n+1)
    
    stack = []
    stack.append(0)
    vertex[0]=(0, 0, 0)
    
    while(stack):
        top = stack.pop()
        ver = vertex[top]
        new_weight = ver[0] + 1
        for j in range(top+1, n+1):
            k = a[top][j]
            if k > -1:
                v = vertex[j]
                if v[0]>new_weight:
                    if v[1] == -1:
                        stack.append(j)
                    vertex[j] = (new_weight, top, k)
    
    
    # Извлечение пути
    
    rver = vertex[n]
    if rver[1] == -1: #Мы не достигли конца
        print('No solution.')
    else:
        way = []
        pos = n
        while pos != 0:
            v = vertex[pos]
            way.insert(0,words[v[2]])
            pos = v[1]
        print(' '.join(way))
    

    其余的你可能明白。

    • 4
  2. slippyk
    2020-10-11T13:45:27Z2020-10-11T13:45:27Z

    另一种解决方案。通过所有测试。

    # Класс, описывающий структуру вершин графа
    class Vertex(object):
        def __init__(self, value, predecessor):
            # Слово
            self.value = value
            # Список вершин-наследников = вершина предка + длина слова
            self.successor = predecessor + len(value)
            # Метка посещения вершины
            self.is_explored = False
    
        def __eq__(self, other):
            return self.successor == other.successor
    
    
    # Функция перевода слова в его цифровое представление
    def get_number(value):
        letters = {
            'i': '1', 'j': '1', 'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3', 'f': '3', 'g': '4', 'h': '4', 'k': '5',
            'l': '5', 'm': '6', 'n': '6', 'p': '7', 'r': '7', 's': '7', 't': '8', 'u': '8', 'v': '8', 'w': '9', 'x': '9',
            'y': '9', 'o': '0', 'q': '0', 'z': '0'
        }
        return ''.join([letters[ch] for ch in value])
    
    
    # Возвращает список всех возможных вершин слова
    def get_vertex(edge, path):
        start = 0
        while True:
            try:
                vertex = path.index(edge, start)
                yield (vertex)
                start = vertex + 1
            except ValueError:
                break
    
    
    # Функция нахождения кратчайшего пути методом поиска в глубину (BFS)
    def bfs_shortest_path(graph, start, goal):
        queue = [[vertex] for vertex in graph[start]]
    
        while queue:
            path = queue.pop(0)
            node = path[-1]
            if node.is_explored:
                continue
            try:
                neighbours = graph[node.successor]
                for neighbour in neighbours:
                    new_path = list(path)
                    new_path.append(neighbour)
                    queue.append(new_path)
                    if neighbour.successor == goal:
                        return new_path
            except KeyError:
                pass
    
            node.is_explored = True
    
        return None
    
    
    if __name__ == '__main__':
        while True:
            phone = input()
            if phone == '-1':
                break
    
            # Метка существования слова, с которого начинается номер
            is_start = False
            # Метка существования возможного результата
            is_result = False
            result = ''
            # Граф
            dictionary = {}
    
            for _ in range(int(input())):
                word = input()
                if is_result:
                    continue
                number = get_number(word)
                if number == phone:
                    is_result = True
                    result = word
                else:
                    for position in get_vertex(number, phone):
                        if position == 0:
                            is_start = True
                        vertex_word = Vertex(word, position)
                        try:
                            if any(map(lambda w: w == vertex_word, dictionary[position])):
                                continue
                            dictionary[position] += [vertex_word]
                        except KeyError:
                            dictionary[position] = [vertex_word]
    
            if is_result:
                print(result)
                continue
            if is_start:
                result = bfs_shortest_path(dictionary, 0, len(phone))
                if result:
                    print(' '.join([word.value for word in result]))
                    continue
                print('No solution.')
            else:
                print('No solution.')
    
    • 2

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5