Livestock Lineup
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 vacas, hay ó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: 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)
breakSolución con grafos
Esta solución se cubre en el módulo Introducción a grafos.