diff --git a/inclusao-de-subintervalos/arthur-dolival-inclusao-de-subintervalos-tutorial.pdf b/inclusao-de-subintervalos/arthur-dolival-inclusao-de-subintervalos-tutorial.pdf new file mode 100644 index 0000000..584eca6 Binary files /dev/null and b/inclusao-de-subintervalos/arthur-dolival-inclusao-de-subintervalos-tutorial.pdf differ diff --git a/inclusao-de-subintervalos/arthur-dolival-inclusao-de-subintervalos-tutorial.tex b/inclusao-de-subintervalos/arthur-dolival-inclusao-de-subintervalos-tutorial.tex new file mode 100644 index 0000000..85ca4a8 --- /dev/null +++ b/inclusao-de-subintervalos/arthur-dolival-inclusao-de-subintervalos-tutorial.tex @@ -0,0 +1,49 @@ +\documentclass[10pt]{article} +\usepackage[utf8]{inputenc} +\usepackage{amsmath,amsthm,amssymb} +\usepackage{fullpage} +\usepackage{url} +\pagenumbering{gobble} +\usepackage{hyperref} +\usepackage{graphicx} +\input{statement/preamble.tex} +\title{ Tutorial: Inclusão de Subintervalos} +\author{} +\date{} +\begin{document} +\maketitle +Nesse problema, devemos ordenar os intervalos $(a_i, b_i)$: + +\begin{itemize} + \item Em ordem crescente de $a_i$. + \item Em caso de empate, em ordem decrescente de $b_i$. +\end{itemize} + +Em seguida, devemos iterar sobre os intervalos ordenados, mantendo o maior valor de $b_i$ +visto até o momento. Se encontrarmos um intervalo $(a_i, b_i)$ tal que $b_i$ seja menor ou +igual ao maior valor de $b_i$ visto até o momento, então esse intervalo é coberto por um +intervalo anterior e podemos descartá-lo. Caso contrário, atualizamos o maior valor de +$b_i$ visto até o momento. + +O algoritmo abaixo implementa essa lógica. + +\begin{algoritmo} +\caption{\Call{interval-cover}{$I$}} +\KwIn{Lista de intervalos $I[0,n-1]$} +\KwOut{Lista de intervalos $I'$ não cobertos por nenhum outro intervalo} +$I' \gets \emptyset$\; +\Call{sort}{$I$} \tcp{Ordena os intervalos com critérios especificados} +$\max_b \gets -\infty$\; +\ForEach{$(a_i, b_i) \in I$}{ + \If{$b_i > \max_b$}{ + $I'.\Call{append}{(a_i,b_i)}$\; + $\max_b \gets b_i$\; + } +} +\Return{$I'$}\; +\end{algoritmo} + + +\section*{Análise} + +O passo de ordenação tem complexidade $\Theta(n \lg n)$ e domina o custo do algoritmo.\end{document} diff --git a/inclusao-de-subintervalos/inclusao-de-subintervalos-tutorial.pdf b/inclusao-de-subintervalos/inclusao-de-subintervalos-tutorial.pdf new file mode 100644 index 0000000..ba04b33 Binary files /dev/null and b/inclusao-de-subintervalos/inclusao-de-subintervalos-tutorial.pdf differ diff --git a/inclusao-de-subintervalos/inclusao-de-subintervalos-tutorial.tex b/inclusao-de-subintervalos/inclusao-de-subintervalos-tutorial.tex new file mode 100644 index 0000000..85ca4a8 --- /dev/null +++ b/inclusao-de-subintervalos/inclusao-de-subintervalos-tutorial.tex @@ -0,0 +1,49 @@ +\documentclass[10pt]{article} +\usepackage[utf8]{inputenc} +\usepackage{amsmath,amsthm,amssymb} +\usepackage{fullpage} +\usepackage{url} +\pagenumbering{gobble} +\usepackage{hyperref} +\usepackage{graphicx} +\input{statement/preamble.tex} +\title{ Tutorial: Inclusão de Subintervalos} +\author{} +\date{} +\begin{document} +\maketitle +Nesse problema, devemos ordenar os intervalos $(a_i, b_i)$: + +\begin{itemize} + \item Em ordem crescente de $a_i$. + \item Em caso de empate, em ordem decrescente de $b_i$. +\end{itemize} + +Em seguida, devemos iterar sobre os intervalos ordenados, mantendo o maior valor de $b_i$ +visto até o momento. Se encontrarmos um intervalo $(a_i, b_i)$ tal que $b_i$ seja menor ou +igual ao maior valor de $b_i$ visto até o momento, então esse intervalo é coberto por um +intervalo anterior e podemos descartá-lo. Caso contrário, atualizamos o maior valor de +$b_i$ visto até o momento. + +O algoritmo abaixo implementa essa lógica. + +\begin{algoritmo} +\caption{\Call{interval-cover}{$I$}} +\KwIn{Lista de intervalos $I[0,n-1]$} +\KwOut{Lista de intervalos $I'$ não cobertos por nenhum outro intervalo} +$I' \gets \emptyset$\; +\Call{sort}{$I$} \tcp{Ordena os intervalos com critérios especificados} +$\max_b \gets -\infty$\; +\ForEach{$(a_i, b_i) \in I$}{ + \If{$b_i > \max_b$}{ + $I'.\Call{append}{(a_i,b_i)}$\; + $\max_b \gets b_i$\; + } +} +\Return{$I'$}\; +\end{algoritmo} + + +\section*{Análise} + +O passo de ordenação tem complexidade $\Theta(n \lg n)$ e domina o custo do algoritmo.\end{document} diff --git a/inclusao-de-subintervalos/src/caio.cpp b/inclusao-de-subintervalos/src/caio.cpp new file mode 100644 index 0000000..f344978 --- /dev/null +++ b/inclusao-de-subintervalos/src/caio.cpp @@ -0,0 +1,31 @@ +#include + +using namespace std; + +int main() { + int n; + cin >> n; + + priority_queue> pq; + int a, b; + for (int i = 0; i < n; i++) { + cin >> a >> b; + pq.push({-a, b}); + } + + int count = 0; + int end = -1; + while (!pq.empty()) { + auto [_, e] = pq.top(); + pq.pop(); + + if (e > end) { + count++; + end = e; + } + } + + cout << count << endl; + + return 0; +} \ No newline at end of file diff --git a/inclusao-de-subintervalos/src/wa.cpp b/inclusao-de-subintervalos/src/wa.cpp new file mode 100644 index 0000000..0ea10e6 --- /dev/null +++ b/inclusao-de-subintervalos/src/wa.cpp @@ -0,0 +1,66 @@ +#include + +using namespace std; + +bool comp(pair &a, pair &b) { + if (a.first != b.first) { + return a.first < b.first; + } + return a.second > b.second; +} + +bool intersecting(pair &a, pair &b) { + return a.second >= b.first; +} + +int main(){ + int n; cin >> n; + + vector> intervals(n); + for (int i = 0; i < n; i++) { + cin >> intervals[i].first; + cin >> intervals[i].second; + } + + sort(intervals.begin(), intervals.end(), comp); + + // first sort by start time, if two intervals start at the same time the one with the highest end time comes first + // always include the first interval + // keep track of the last included interval so far + // while there are intervals intersecting with the last included interval take the one with the highest ending value + // + // if there is some intersecting interval check if its end time is greater than the last included interval end time, if so include it and update count, else repeat process from the last intersecting interval + // if no intervals intersect with the last included interval then just process the next interval in order + + // in both cases update the count by 1 + + int curInterval = 1, lastIncludedInterval = 0, count = 1; + while (curInterval < n) { // curInterval holds the first interval thaat was not processed yet + int bestIntersectingInterval = lastIncludedInterval, j = curInterval; + while (j < n && intersecting(intervals[lastIncludedInterval], intervals[j])) { + int bestEndTime = intervals[bestIntersectingInterval].second; + int endTime = intervals[j].second; + if (endTime > bestEndTime) { + bestIntersectingInterval = j; + } + j++; + } + + if (bestIntersectingInterval != lastIncludedInterval) { + lastIncludedInterval = bestIntersectingInterval; + count++; + } else { + if (j == n) break; // this interval alredy covers every remaining interval + + lastIncludedInterval = j; + count++; + } + + if (curInterval == j) curInterval++; + else curInterval = j; + } + + cout << count << endl; + + return 0; +} \ No newline at end of file