Résoudre avec Python [100 questions passées que les débutants et les intermédiaires devraient résoudre] (028 --033 recherche de priorité de largeur)

1. Objet

Résolvez 100 questions passées que les débutants et les intermédiaires devraient résoudre en Python. L'objectif est de devenir bleu clair lorsque vous avez terminé de tout résoudre.

Cet article s'intitule "Recherche de priorité de largeur 028 --033".

2. Résumé

dfsSi possiblebfsEst presque le même. La différence est que `deque ()` apparaît depuis `pop ()` ʻin` `DFS``` et` popleft () dans`` BFS```. Utilisez ``.

3. Histoire principale

028 --033 Recherche de priorité de largeur

028. ALDS_11_C --Width priority search

image.png

Répondre


from collections import deque

n = int(input())
graph = [[] for _ in range(n+1)]
for _ in range(n):
    i, num, *nodes = map(int, input().split()) # *Collecter plus
    graph[i] = nodes #Graphique dirigé
visited = [-1] * (n+1)

q = deque()
q.append(1)
visited[1] = 0

while q:
    node = q.popleft()

    for next in graph[node]:
        if visited[next] != -1:
            continue
        q.append(next)
        visited[next] = visited[node] + 1
        
for i, num in enumerate(visited[1:]):
    print(i+1, num)

C'est un problème fondamental. Si vous créez votre propre moule ici, vous pourrez résoudre d'autres problèmes avec juste quelques ajustements.

bfsSi vous montrez approximativement le flux de

  1. Utilisez `` visité '' `pour créer une liste de destinations de recherche.
  2. Préparez `` deque () '' pour le moment et entrez la valeur initiale
  3. Tourner `while``` jusqu'à ce que` deque () `` `soit vide
  4. Utilisez popleft () '' pour récupérer la valeur first in first out
  5. Examinez le `` graphe '' des valeurs récupérées pour trouver la destination
  6. Déterminez si la destination a été recherchée
  7. Mettez à jour append et `` `visité``` si vous ne recherchez pas

est.


029. AtCoder Beginner Contest 007 C --Width priority search

image.png image.png image.png

Répondre


from collections import deque

R, C = map(int, input().split())
sy, sx = map(int, input().split())
sy -= 1 #Fixé à 0 index
sx -= 1
gy, gx = map(int, input().split())
gy -= 1 #Fixé à 0 index
gx -= 1
grid = [list(input()) for _ in range(R)]
visited = [[-1] * C for _ in range(R)]
moves = [(1, 0), (0, 1), (-1, 0), (0, -1)]

q = deque()
q.append((sy, sx))
visited[sy][sx] = 0

while q:
    start_y, start_x = q.popleft()

    for dy, dx in moves:
        moved_y = start_y + dy
        moved_x = start_x + dx

        if grid[moved_y][moved_x] == '#':
            continue
        if visited[moved_y][moved_x] != -1:
            continue
        visited[moved_y][moved_x] = visited[start_y][start_x] + 1
        q.append((moved_y, moved_x))

print(visited[gy][gx])

Ceci est typique du typique. Je m'en souviendrai pour le moment.


030. JOI 2011 Qualifying 5-Cheese

image.png image.png

Répondre

from collections import deque

def bfs(start_y, start_x, target_cheese, H, W, grid):

    visited = [[-1] * W for _ in range(H)]
    moves = [(1, 0), (0, 1), (-1, 0), (0, -1)]
    q = deque()
    q.append((start_y, start_x))
    visited[start_y][start_x] = 0

    while q:
        y, x = q.popleft()
        for dy, dx in moves:
            moved_y = y + dy
            moved_x = x + dx

            if moved_y < 0 or H - 1 < moved_y or moved_x < 0 or W -1 < moved_x:
                continue
            if grid[moved_y][moved_x] == 'X':
                continue
            if visited[moved_y][moved_x] != -1:
                continue
            if grid[moved_y][moved_x] == target_cheese:
                visited[moved_y][moved_x] = visited[y][x] + 1
                return visited[moved_y][moved_x]
 
            visited[moved_y][moved_x] = visited[y][x] + 1
            q.append((moved_y, moved_x))
            

if __name__ == "__main__":
    H, W, N = map(int, input().split())
    grid = [list(input()) for _ in range(H)] #S commence au nid, les nombres sont la dureté du fromage, X est l'obstacle,.Est un terrain vague
    #Les rats mangent du fromage dans l'ordre numérique
    #Considérez BFS de chaque nombre au suivant
    #Saisissez d'abord le début et la position de chaque numéro
    start_y, start_x = 0, 0
    cheese = [(0, 0) for _ in range(10)] #Valeur initiale(0, 0)Garder
    count = 0 #Mettre le nombre de fromages en compte
    for row in range(H):
        for col in range(W):
            if grid[row][col] == '.' or grid[row][col] == 'X':
                continue
            elif grid[row][col] == 'S':
                start_y, start_x = row, col
            else:
                grid[row][col] = int(grid[row][col]) #Changer le contenu de la grille en nombres
                cheese[int(grid[row][col])] = (row, col)
                count += 1
                
    # ------- [Explorer tous les points] ----------
    target_cheese = 1
    time_count = 0
    while target_cheese <= count:
        time_count += bfs(start_y, start_x, target_cheese, H, W, grid)
        start_y, start_x = cheese[target_cheese]
        target_cheese += 1

    print(time_count)

La mise en œuvre est un peu lourde. À partir de l'énoncé du problème, la souris mange du fromage avec le plus petit nombre au fromage avec le plus grand nombre dans l'ordre, il semble donc que vous devriez faire BFS '' de chaque numéro au numéro suivant. Alors, définissez BFS '', qui a une position de départ et une position de but fixes, dans l'ordre des numéros de fromage. s1debfs12debfs23debfs ・・・と行っていき、合計de最短距離が答えとなります。


031. JOI 2012 Qualifying 5 --Illumination

image.png image.png

Répondre


#Ajoutez tous les 0 en haut, en bas, à gauche et à droite de la ceinture,
#Coordonner(0,0)Additionnez le nombre de 1 d'où chaque point 0 qui peut être atteint

from collections import deque

# ---------- [Comptez le nombre de bâtiments adjacents à des endroits sans bâtiments] --------------
def check_walls(y, x, grid, W, H, even_moves, add_moves):
    count = 0

    if y % 2 == 0:
        moves = even_moves
    else:
        moves = add_moves
    
    for dy, dx in moves:
        moved_y = y + dy
        moved_x = x + dx
        if moved_y < 0 or H + 1 < moved_y or moved_x < 0 or W + 1 < moved_x:
            continue
        if grid[moved_y][moved_x] == 1:
            count += 1
    
    return count

if __name__ == "__main__":
    # ---------- [Reçu d'entrée] --------------
    W, H = map(int, input().split())
    grid = []
    grid.append([0] * (W+2))
    for _ in range(H):
        temp = list(map(int, input().split()))
        temp = [0] + temp + [0]
        grid.append(temp)
    grid.append([0] * (W+2))
    visited = [[-1] * (W+2) for _ in range(H+2)]
    answer_count = 0
    # ---------- [Pair et impair ont des directions de mouvement différentes] --------------
    even_moves = [(-1, -1), (-1, 0), (0, 1), (1, 0), (1, -1), (0, -1)] #Dans le sens des aiguilles d'une montre à partir du coin supérieur gauche
    add_moves = [(-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (0, -1)] #Dans le sens des aiguilles d'une montre à partir du coin supérieur gauche
    # ---------- [Réglage de la valeur initiale] --------------
    q = deque()
    q.append((0, 0)) # (0, 0)Effectuer des BFS pour les endroits où il n'y a pas de bâtiments accessibles depuis
    count = check_walls(0, 0, grid, W, H, even_moves, add_moves) #Comptez le nombre de bâtiments adjacents
    visited[0][0] = count
    answer_count += count
    # ---------- [BFS a commencé] --------------
    while q:
        y, x = q.popleft()

        if y % 2 == 0:
            moves = even_moves
        else:
            moves = add_moves
        
        for dy, dx in moves:
            moved_y = y + dy
            moved_x = x + dx
            if moved_y < 0 or H + 1 < moved_y or moved_x < 0 or W + 1 < moved_x:
                continue
            if grid[moved_y][moved_x] == 1:
                continue
            if visited[moved_y][moved_x] != -1:
                continue
            q.append((moved_y, moved_x))
            count = check_walls(moved_y, moved_x, grid, W, H, even_moves, add_moves)
            visited[moved_y][moved_x] = count
            answer_count += count

    print(answer_count)

De nombreux problèmes sont basés sur un modèle de grille, mais ce problème est légèrement différent car un carré est hexagonal. Cependant, la façon de penser et de résoudre ne change pas beaucoup, et la seule chose à changer est de savoir comment définir les coordonnées de mouvement de BFS ''. Plus précisément, dans mon cas, c'est la partie définie par se déplace ''.

Dans ce problème, lorsque les coordonnées `` y '' sont paires et impaires, les destinations qui peuvent être déplacées de chaque carré sont différentes. Par conséquent, chacun est défini comme suit.


even_moves = [(-1, -1), (-1, 0), (0, 1), (1, 0), (1, -1), (0, -1)] #Dans le sens des aiguilles d'une montre à partir du coin supérieur gauche
add_moves = [(-1, 0), (-1, 1), (0, 1), (1, 1), (1, 0), (0, -1)] #Dans le sens des aiguilles d'une montre à partir du coin supérieur gauche

S'il s'agit d'un modèle de grille normal, la composante de mouvement haut / bas / gauche / droite ou haut / bas / gauche / droite + diagonale est définie comme suit, donc seulement ici est différente.


moves = [(1, 0), (0, 1), (-1, 0), (0, -1)] #Seulement en haut, en bas, à gauche et à droite

moves = [(1, 0), (0, 1), (-1, 0), (0, -1), (1, 1), (-1, -1), (1, -1), (-1, 1)] #Haut bas Gauche Droite+Lorsque la diagonale

Si vous maintenez ici, le reste sera résolu comme la politique suivante

  1. La grande politique est de rechercher des «emplacements sans bâtiments» avec «BFS», de compter les bâtiments adjacents à chaque emplacement, et le total est la réponse.
  2. Pour cela, ajoutez d'abord des "lieux sans bâtiments" en haut, en bas, à gauche et à droite de la grille reçue par défaut.
  3. BFS``` est exécuté à partir du coin supérieur gauche (0, 0) de la grille
  4. À ce moment-là, ce n'est pas le 0, 1 habituel qui est enregistré dans `` visité '', mais le nombre de bâtiments adjacents
  5. Par conséquent, créez une fonction `` check_walls '' pour compter le nombre de bâtiments adjacents.
  6. Lors de l'exécution de BFS, soyez prudent car le comportement diffère selon que `` y``` est pair ou impair.
  7. La réponse est la somme des nombres renvoyés par `check_walls``` après avoir traversé` BFS```.

est.


032. AOJ 1166 - Labyrinthe et ordre

image.png image.png

Répondre


from collections import deque

def main(w, h):
    tatebou = []
    yokobou = [[0] * w]
    for _ in range(h-1):
        tate = [0] + list(map(int, input().split()))
        yoko = list(map(int, input().split()))
        tatebou.append(tate)
        yokobou.append(yoko)
    tate = [0] + list(map(int, input().split()))
    tatebou.append(tate)
    visited = [[0] * w for _ in range(h)]
    moves = [(1, 0), (-1, 0), (0, 1), (0, -1)]

    q = deque()
    q.append((0, 0))
    visited[0][0] = 1

    while q:
        y, x = q.popleft()

        for dy, dx in moves:
            moved_y = y + dy
            moved_x = x + dx

            if dy == 1 and dx == 0:
                if moved_y < 0 or h-1 < moved_y or moved_x < 0 or w-1 < moved_x: #En dehors du labyrinthe
                    continue
                if visited[moved_y][moved_x] != 0:
                    continue
                if yokobou[moved_y][moved_x] == 1: #Lorsque vous descendez, vous ne pouvez pas vous déplacer lorsque la destination est 1.
                    continue
                visited[moved_y][moved_x] = visited[y][x] + 1
                q.append((moved_y, moved_x))

            elif dy == -1 and dx == 0:
                if moved_y < 0 or h-1 < moved_y or moved_x < 0 or w-1 < moved_x: #En dehors du labyrinthe
                    continue
                if visited[moved_y][moved_x] != 0:
                    continue
                if yokobou[y][moved_x] == 1: #Quand tu montes, pas quand tu as 1
                    continue
                visited[moved_y][moved_x] = visited[y][x] + 1
                q.append((moved_y, moved_x))

            elif dy == 0 and dx == 1:
                if moved_y < 0 or h-1 < moved_y or moved_x < 0 or w-1 < moved_x: #En dehors du labyrinthe
                    continue
                if visited[moved_y][moved_x] != 0:
                    continue
                if tatebou[moved_y][moved_x] == 1: #Lorsque vous allez vers la droite, vous ne pouvez pas vous déplacer lorsque la destination est 1.
                    continue
                visited[moved_y][moved_x] = visited[y][x] + 1
                q.append((moved_y, moved_x))
            else: # dy == 0 and dx == -1
                if moved_y < 0 or h-1 < moved_y or moved_x < 0 or w-1 < moved_x: #En dehors du labyrinthe
                    continue
                if visited[moved_y][moved_x] != 0:
                    continue
                if tatebou[moved_y][x] == 1: #Lorsque vous allez à gauche, vous ne pouvez pas quand vous êtes 1.
                    continue
                visited[moved_y][moved_x] = visited[y][x] + 1
                q.append((moved_y, moved_x))
            
    return visited[h-1][w-1]


if __name__ == "__main__":

    answer_list = []
    while True:
        w, h = map(int, input().split())
        if w == 0 and h == 0:
            break

        answer = main(w, h)
        answer_list.append(answer)

    for answer in answer_list:
        print(answer)


Fondamentalement, c'est la même chose que le problème 29. La différence est le jugement de succès. Le problème 29 est facile parce que c'était un jugement frappant que "vous ne pouvez pas aller à la masse elle-même", mais ce problème n'est pas "masse" mais "mur". Par conséquent, il est nécessaire de séparer les cas qui ne sont pas nécessaires pour un `` BFS '' normal. Plus précisément, il est nécessaire de modifier le jugement de frappe comme indiqué ci-dessous en fonction de la façon dont vous vous déplacez vers le haut, le bas, la gauche et la droite.



            if dy == 1 and dx == 0:
                if yokobou[moved_y][moved_x] == 1: #Lorsque vous descendez, vous ne pouvez pas vous déplacer lorsque la destination est 1.
                    continue
            elif dy == -1 and dx == 0:
                if yokobou[y][moved_x] == 1: #Quand tu montes, pas quand tu as 1
                    continue
            elif dy == 0 and dx == 1:
                if tatebou[moved_y][moved_x] == 1: #Lorsque vous allez vers la droite, vous ne pouvez pas vous déplacer lorsque la destination est 1.
                    continue
            else: # dy == 0 and dx == -1
                if tatebou[moved_y][x] == 1: #Lorsque vous allez à gauche, vous ne pouvez pas quand vous êtes 1.
                    continue

À part ce jugement frappé, écrivez simplement normalement.


  1. AtCoder Beginner Contest 088 D - Grid Repainting image.png image.png

Répondre


#Seuls les blancs bougent(0,0)De(H-1, W-1)aller à
#À ce moment-là, augmentez le noir autant que possible
#La réponse est le blanc total moins la distance la plus courte

from collections import deque


H, W = map(int, input().split())
grid = [list(input()) for _ in range(H)] # .Est blanc,#Est noir
visited = [[-1] * W for _ in range(H)]
moves = [(1, 0), (0, 1), (-1, 0), (0, -1)]

q = deque()
q.append((0, 0))
visited[0][0] = 0

while q:
    y, x = q.popleft()

    for dy, dx in moves:
        moved_y = y + dy
        moved_x = x + dx

        if moved_y < 0 or H-1 < moved_y or moved_x < 0 or W-1 < moved_x:
            continue
        if grid[moved_y][moved_x] == '#':
            continue
        if visited[moved_y][moved_x] != -1:
            continue

        visited[moved_y][moved_x] = visited[y][x] + 1
        q.append((moved_y, moved_x))

min_route = visited[H-1][W-1]

if min_route == -1:
    answer = -1
else:
    total_white = 0
    for row in grid:
        total_white += row.count('.')

    answer = total_white - min_route - 1

print(answer)


C'est assez facile si vous pouvez résoudre d'autres problèmes. Si vous mâchez le problème et l'interprétez, la réponse est "le nombre de peintures noires lors du déplacement du coin supérieur gauche vers le coin inférieur droit". Pour rendre cela plus facile à résoudre, c'est "le nombre d'autres endroits qui ne passent pas lors du déplacement du haut à gauche vers le bas à droite par la distance la plus courte". Une fois que vous savez cela, vous pouvez généralement calculer la distance la plus courte avec `` BFS '' et la soustraire du tout.

Donc, la politique est

  1. `(0,0)` start, (H-1, W-1) but pour calculer la distance la plus courte min_route```
  2. Calculez le nombre total de blancs `total_white `
  3. La réponse est `total_white moins min_route``` ( min_route``` est un départ nul, donc ajoutez -1)

est.


Recommended Posts

Résoudre avec Python [100 questions passées que les débutants et les intermédiaires devraient résoudre] (028 --033 recherche de priorité de largeur)
Résoudre avec Python [100 questions passées que les débutants et les intermédiaires devraient résoudre] (024 --027 Recherche de priorité en profondeur)
Résoudre avec Python [100 anciennes questions sélectionnées que les débutants et les intermédiaires devraient résoudre] (015 --017 Recherche complète: Recherche complète en avant)
Résoudre avec Python [100 questions passées sélectionnées que les débutants et les intermédiaires devraient résoudre] (010 --014 Recherche complète: Recherche complète de bits)
Résoudre avec Python [100 questions passées sélectionnées que les débutants et les intermédiaires devraient résoudre] (001 --004 Toutes les recherches: Toutes les énumérations)
Résolution avec Python [100 questions passées que les débutants et les intermédiaires devraient résoudre] (053 --055 Méthode de planification dynamique: Autres)
[Python] J'ai essayé de résoudre 100 questions passées que les débutants et les intermédiaires devraient résoudre [Partie 7/22]
[Python] J'ai essayé de résoudre 100 questions passées que les débutants et les intermédiaires devraient résoudre [Partie 4/22]
[Python] J'ai essayé de résoudre 100 questions passées que les débutants et les intermédiaires devraient résoudre [Part3 / 22]
[Python] J'ai essayé de résoudre 100 questions passées que les débutants et les intermédiaires devraient résoudre [Partie 1/22]
[Python] J'ai essayé de résoudre 100 questions passées que les débutants et les intermédiaires devraient résoudre [Partie 6/22]
Résoudre avec Python [100 questions passées que les débutants et les intermédiaires devraient résoudre] (056 --059 Problème de l'itinéraire le plus court: méthode Dyxtra)
Résoudre avec Python [100 questions que les débutants et les intermédiaires devraient résoudre] (034-038 Méthode de planification dynamique: Knapsack DP basic)
Résolvez avec Python [100 questions passées que les débutants et les intermédiaires devraient résoudre] (039 --045 Méthode de planification dynamique: variante Knapsack DP)
Résoudre avec Python [100 questions passées sélectionnées que les débutants et les intermédiaires devraient résoudre] (005 --- 009 Toutes les recherches: Toutes les énumérations pour réduire le nombre de rues en concevant)
Raisonnement causal et recherche causale par Python (pour les débutants)
1er test pratique d'algorithme Résoudre les questions passées avec python
[Python] Recherche de priorité de profondeur et recherche de priorité de largeur
Résolution avec Ruby et Python AtCoder ABC151 D Recherche de priorité de largeur
2e test pratique de l'algorithme Résoudre les questions précédentes avec python (inachevé)
Résolution avec Ruby, Perl, Java et Python AtCoder AGC 033 A Recherche de priorité de largeur
Rechercher et télécharger automatiquement des vidéos YouTube avec Python
Créons une application capable de rechercher des images similaires avec Python et Flask Part1
Créons une application capable de rechercher des images similaires avec Python et Flask Part2
[Pour les professionnels de la compétition débutants] J'ai essayé de résoudre 40 questions AOJ "ITP I" avec python
Résolvez des équations différentielles normales simultanées avec Python et SymPy.
Exploration avec Python et Twitter API 1 - Fonction de recherche simple
Implémenter la recherche de priorité en profondeur (DFS) et la recherche de priorité de largeur (BFS) en python
Recherche séquentielle avec Python
Résolvez AtCoder 167 avec python
Exercice Python Recherche prioritaire sur 1 largeur
Résoudre des maths avec Python
Dichotomie avec python
Dichotomie avec Python 3
Résolvez POJ 2386 avec python
Résolution avec Ruby et Python AtCoder ABC133 D Somme cumulée
Résolvez le livre en spirale (algorithme et structure de données) avec python!
Résoudre les problèmes d'AtCoder Boot camp pour les débutants (moyen 100) avec python
Résumé des modules qui automatisent et facilitent l'installation de WebDriver avec Python
[Python] Résoudre des équations avec sympy
Programmation avec Python et Tkinter
[Python] BFS (recherche de priorité de largeur) ABC168D
Chiffrement et déchiffrement avec Python
Résolvez AtCoder ABC166 avec python
Python et matériel - Utilisation de RS232C avec Python -
Recherche de priorité de largeur / recherche bidirectionnelle (édition Python)
Recherche de bits complète avec Python
python avec pyenv et venv
Les moteurs de recherche fonctionnent avec python
Rechercher des tweets Twitter avec Python
Rationalisez la recherche Web avec Python
Fonctionne avec Python et R
Je veux résoudre APG4b avec Python (seulement 4.01 et 4.04 au chapitre 4)
Exploration avec Python et Twitter API 2-Implémentation de la fonction de recherche d'utilisateurs
AtCoder ARC104 B Somme cumulative résolue en Ruby, Python et Java
Résolvez le problème du sac à dos Python avec la méthode de branche et liée
Résolvez les problèmes de somme partielle avec une recherche complète en Python
À propos de la recherche peu complète qui apparaît souvent chez les professionnels de la concurrence Aux yeux des débutants avec python