Skip to Content

Livestock Lineup

Análisis oficial (C++) 

Solución en video

Por Melody Yu

Video de YouTube (xed_5FjVMoo)

Código de la solución en video
#include <bits/stdc++.h> using namespace std; int N; int main() { freopen("lineup.in", "r", stdin); freopen("lineup.out", "w", stdout); cin >> N; vector<pair<string, string>> restrictions; for (int i = 0; i < N; i++) { string a, t, b; cin >> a; cin >> t >> t >> t >> t; cin >> b; restrictions.push_back({a, b}); } vector<string> cows = {"Bessie", "Buttercup", "Belinda", "Beatrice", "Bella", "Blue", "Betsy", "Sue"}; sort(cows.begin(), cows.end()); int count = 0; while (next_permutation(cows.begin(), cows.end())) { bool passed = true; for (auto p : restrictions) { string cow1 = p.first; string cow2 = p.second; auto a = find(cows.begin(), cows.end(), cow1); auto b = find(cows.begin(), cows.end(), cow2); if (abs(a - b) != 1) { passed = false; } } if (passed) { break; } } for (auto cow : cows) { cout << cow << endl; } }
import java.io.*; import java.util.*; public class Lineup { static ArrayList<String> restrictionsA; static ArrayList<String> restrictionsB; private static ArrayList<String> permutations(ArrayList<String> s) { // 1. encuentra el mayor k tal que c[k] < c[k+1] int first = s.size() - 2; for (; first >= 0; first--) { if (s.get(first).compareTo(s.get(first + 1)) < 0) break; } if (first == -1) return null; // 2. encuentra el último índice toSwap tal que c[k] < c[toSwap] int toSwap = s.size() - 1; for (; toSwap >= 0; toSwap--) { if (s.get(first).compareTo(s.get(toSwap)) < 0) break; } // 3. intercambiamos los elementos con índices first y last Collections.swap(s, first++, toSwap); // 4. invertimos la secuencia de k+1 a n (inclusive) toSwap = s.size() - 1; while (first < toSwap) Collections.swap(s, first++, toSwap--); return s; } private static int findIndex(ArrayList<String> perm, String cow) { for (int i = 0; i < perm.size(); i++) { if (cow.equals(perm.get(i))) { return i; } } return -1; } private static boolean check(ArrayList<String> perm) { boolean passed = true; for (int i = 0; i < restrictionsA.size(); i++) { String cow1 = restrictionsA.get(i); String cow2 = restrictionsB.get(i); int a = findIndex(perm, cow1); int b = findIndex(perm, cow2); if (Math.abs(a - b) != 1) { passed = false; break; } } if (passed) { return true; } else { return false; } } public static void main(String[] args) throws IOException { Lineup.Kattio io = new Lineup.Kattio("lineup"); int N = io.nextInt(); ArrayList<String> cows = new ArrayList<String>( Arrays.asList("Bessie", "Buttercup", "Belinda", "Beatrice", "Bella", "Blue", "Betsy", "Sue")); restrictionsA = new ArrayList<String>(); restrictionsB = new ArrayList<String>(); for (int i = 0; i < N; i++) { String a = io.next(); io.next(); io.next(); io.next(); io.next(); String b = io.next(); restrictionsA.add(a); restrictionsB.add(b); } Collections.sort(cows); while (cows != null) { if (check(cows)) { for (String c : cows) { io.println(c); } break; } cows = permutations(cows); } io.close(); } // CodeSnip{Kattio} }

Explicación

Como solo hay 88 vacas, hay 8!=403208! = 40320 órdenes distintos posibles, que es suficientemente pequeño como para probarlos todos y seguir pasando el problema a tiempo.

Si los generamos en orden alfabético y encontramos un orden que satisface todas las restricciones dadas, entonces podemos parar e imprimir la respuesta ahí mismo.

Implementación

Complejidad temporal: O(N)\mathcal{O}(N)Notemos que no hace falta incluir el tiempo que toma construir las permutaciones e iterar por ellas porque son factores constantes.

#include <bits/stdc++.h> using namespace std; const int RESTRICT_LEN = 6; // lista de vacas, en orden alfabético const vector<string> COWS = {"Beatrice", "Belinda", "Bella", "Bessie", "Betsy", "Blue", "Buttercup", "Sue"}; vector<vector<string>> orderings; void build(vector<string> ordering) { // terminamos de construir la permutación if ((int)(ordering.size()) == 8) { orderings.push_back(ordering); return; } for (const string &COW : COWS) { if (find(ordering.begin(), ordering.end(), COW) == ordering.end()) { ordering.push_back(COW); build(ordering); ordering.pop_back(); } } } // devuelve el índice de una vaca en un orden int loc(const vector<string> &order, const string &cow) { return find(order.begin(), order.end(), cow) - order.begin(); } int main() { freopen("lineup.in", "r", stdin); freopen("lineup.out", "w", stdout); int n; cin >> n; vector<pair<string, string>> restrictions; for (int i = 0; i < n; i++) { string cow1 = ""; string cow2 = ""; for (int j = 0; j < RESTRICT_LEN; j++) { string word; cin >> word; cow1 = cow1.empty() ? word : cow1; cow2 = word; } restrictions.emplace_back(cow1, cow2); } // construimos todos los órdenes posibles de vacas build({}); for (vector<string> &order : orderings) { bool ok = true; for (const pair<string, string> &rule : restrictions) { if (abs(loc(order, rule.first) - loc(order, rule.second)) > 1) { ok = 0; break; } } if (ok) { for (const string &i : order) { cout << i << '\n'; } break; } } }
import java.io.*; import java.util.*; class Pair<T, U> { T first; U second; public Pair(T first, U second) { this.first = first; this.second = second; } } public class Lineup { private static final int RESTRICT_LEN = 6; // lista de vacas, en orden alfabético private static final List<String> COWS = Arrays.asList( "Beatrice", "Belinda", "Bella", "Bessie", "Betsy", "Blue", "Buttercup", "Sue"); private static List<List<String>> orderings = new ArrayList<>(); private static void build(List<String> ordering) { // terminamos de construir la permutación if (ordering.size() == 8) { orderings.add(new ArrayList<>(ordering)); return; } for (String cow : COWS) { if (!ordering.contains(cow)) { ordering.add(cow); build(ordering); ordering.remove(ordering.size() - 1); } } } // devuelve el índice de una vaca en un orden private static int loc(List<String> order, String cow) { return order.indexOf(cow); } public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new FileReader("lineup.in")); int n = Integer.parseInt(br.readLine().trim()); List<Pair<String, String>> restrictions = new ArrayList<>(); for (int i = 0; i < n; i++) { String[] words = br.readLine().split(" "); restrictions.add(new Pair<>(words[0], words[words.length - 1])); } br.close(); // construimos todos los órdenes posibles de vacas build(new ArrayList<>()); PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("lineup.out"))); for (List<String> order : orderings) { boolean ok = true; for (Pair<String, String> rule : restrictions) { if (Math.abs(loc(order, rule.first) - loc(order, rule.second)) > 1) { ok = false; break; } } if (ok) { for (String cow : order) { pw.println(cow); } break; } } pw.close(); } }
from typing import List # lista de vacas, en orden alfabético COWS = ["Beatrice", "Belinda", "Bella", "Bessie", "Betsy", "Blue", "Buttercup", "Sue"] orderings = [] def build(ordering: List[str]): # terminamos de construir la permutación if len(ordering) == 8: orderings.append(ordering.copy()) return for cow in COWS: if cow not in ordering: ordering.append(cow) build(ordering) ordering.pop() with open("lineup.in") as read: n = int(read.readline()) restrictions = [] for _ in range(n): line = read.readline().split() cow1 = line[0] cow2 = line[-1] restrictions.append((cow1, cow2)) # construimos todos los órdenes posibles de vacas build([]) for order in orderings: for rule in restrictions: if abs(order.index(rule[0]) - order.index(rule[1])) > 1: break else: with open("lineup.out", "w") as written: for cow in order: print(cow, file=written) break

Solución O(N)\mathcal{O}(N) con grafos

Esta solución se cubre en el módulo Introducción a grafos.