Sei sulla pagina 1di 27

Apostila Maratona

To do List -> -> -> -> Apostilar Apostilar Apostilar Apostilar frmulas geomtricas = CELSO mtodos de otimizao = CELSO Grafos Algoritmos Bsicos

Abaixo, mtodos em Java para resolver subproblemas importantes e reincidentes na Maratona de Programao.

Template //No alterar Entrada: Sada: Cdigo: Selection Sort//No alterar Entrada: Sada: Cdigo: public static void SelectionSort(int[] v) { int index_min, aux; for (int i=0; i<v.length; i++) { index_min = i; for (int j=i+1; j<v.length; j++) { if (v[j]<v[index_min]) { index_min=j; } } if(index_min != i){ aux = v[index_min]; v[index_min] = v[i]; v[i] = aux; } } }

QuickSort Entrada: Sada:

Cdigo: public class QuickSort<E extends Comparable<? super E>> { public static final Random RND = new Random(); private void swap(E[] array, int i, int j) { E tmp = array[i]; array[i] = array[j]; array[j] = tmp; } private int partition(E[] array, int begin, int end) { int index = begin + RND.nextInt(end - begin + 1); E pivot = array[index]; swap(array, index, end); for (int i = index = begin; i < end; ++i) { if (array[i].compareTo(pivot) <= 0) { swap(array, index++, i); } } swap(array, index, end); return (index); } private void qsort(E[] array, int begin, int end) { if (end > begin) { int index = partition(array, begin, end); qsort(array, begin, index - 1); qsort(array, index + 1, end); } } public void sort(E[] array) { qsort(array, 0, array.length - 1); } }

Kadane //Kadane's algorithm finds the maximum subarray sum in linear time. Entrada: Sada: Cdigo: public class Kadane { double maxSubarray(double[] a) { double max_so_far = 0; double max_ending_here = 0; for(int i=0; i<a.length; i++) { max_ending_here = Math.max(0, max_ending_here + a[i]); max_so_far = Math.max(max_so_far, max_ending_here);

} return max_so_far; } } Bubble Sort//No alterar http://algowiki.net/wiki/index.php/Bubble_sort Entrada: Sada: Cdigo: public static <T extends Comparable<? super T>> T[] bubblesort(T[] input){ boolean swapped; do{ swapped = false; for(int i=0; i<input.length-1; i++){ if(input[i].compareTo(input[i+1]) > 0){ T tmp = input[i]; input[i] = input[i+1]; input[i+1] = tmp; swapped = true; } } }while(swapped); return input; }

Kruskal //Kruskal's algorithm finds a minimum spanning tree for a connected, weighted, undirected graph. http://alogwiki.net Entrada: Sada: Cdigo: public ArrayList<Edge> getMST(Node[] nodes, ArrayList<Edge> edges){ java.util.Collections.sort(edges); ArrayList<Edge> MST = new ArrayList<Edge>(); DisjointSet<Node> nodeset = new DisjointSet<Node>(); nodeset.createSubsets(nodes); for(Edge e : edges){ if(nodeset.find(e.from) != nodeset.find(e.to)){ nodeset.merge(nodeset.find(e.from), nodeset.find(e.to)); MST.add(e); } } return MST; }

Edmond //Calcula menor ou maior caminho entre dois vrtices de um grafo orientado http://alogwiki.net Entrada: Sada: Cdigo: public class Edmonds { private ArrayList<Node> cycle; public AdjacencyList getMinBranching(Node root, AdjacencyList list){ AdjacencyList reverse = list.getReversedList(); // remove all edges entering the root if(reverse.getAdjacent(root) != null){ reverse.getAdjacent(root).clear(); } AdjacencyList outEdges = new AdjacencyList(); // for each node, select the edge entering it with smallest weight for(Node n : reverse.getSourceNodeSet()){ ArrayList<Edge> inEdges = reverse.getAdjacent(n); if(inEdges.size() == 0) continue; Edge min = inEdges.get(0); for(Edge e : inEdges){ if(e.weight < min.weight){ min = e; } } outEdges.addEdge(min.to, min.from, min.weight); } // detect cycles ArrayList<ArrayList<Node>> cycles = new ArrayList<ArrayList<Node>>(); cycle = new ArrayList<Node>(); getCycle(root, outEdges); cycles.add(cycle); for(Node n : outEdges.getSourceNodeSet()){ if(!n.visited){ cycle = new ArrayList<Node>(); getCycle(n, outEdges); cycles.add(cycle); } } // for each cycle formed, modify the path to merge it into another part of the graph AdjacencyList outEdgesReverse = outEdges.getReversedList(); for(int i=0; i<cycles.size(); i++){ if(cycles.get(i).contains(root)) continue; mergeCycles(cycles.get(i), list, reverse, outEdges, outEdgesReverse); }

return outEdges; } private void mergeCycles(ArrayList<Node> cycle, AdjacencyList list, AdjacencyList reverse, AdjacencyList outEdges, AdjacencyList outEdgesReverse){ ArrayList<Edge> cycleAllInEdges = new ArrayList<Edge>(); Edge minInternalEdge = null; // find the minimum internal edge weight for(Node n : cycle){ for(Edge e : reverse.getAdjacent(n)){ if(cycle.contains(e.to)){ if(minInternalEdge == null || minInternalEdge.weight > e.weight){ minInternalEdge = e; continue; } }else{ cycleAllInEdges.add(e); } } } // find the incoming edge with minimum modified cost Edge minExternalEdge = null; int minModifiedWeight = 0; for(Edge e : cycleAllInEdges){ int w = e.weight - (outEdgesReverse.getAdjacent(e.from).get(0).weight minInternalEdge.weight); if(minExternalEdge == null || minModifiedWeight > w){ minExternalEdge = e; minModifiedWeight = w; } } // add the incoming edge and remove the inner-circuit incoming edge Edge removing = outEdgesReverse.getAdjacent(minExternalEdge.from).get(0); outEdgesReverse.getAdjacent(minExternalEdge.from).clear(); outEdgesReverse.addEdge(minExternalEdge.to, minExternalEdge.from, minExternalEdge.weight); ArrayList<Edge> adj = outEdges.getAdjacent(removing.to); for(int i=0; i<adj.size(); i++){ if(adj.get(i).to == removing.from){ adj.remove(i); break; } } outEdges.addEdge(minExternalEdge.to, minExternalEdge.from, minExternalEdge.weight); } private void getCycle(Node n, AdjacencyList outEdges){ n.visited = true; cycle.add(n); if(outEdges.getAdjacent(n) == null) return; for(Edge e : outEdges.getAdjacent(n)){

if(!e.to.visited){ getCycle(e.to, outEdges); } } } } public class AdjacencyList { private Map<Node, ArrayList<Edge>> adjacencies = new HashMap<Node, ArrayList<Edge>>(); public void addEdge(Node source, Node target, int weight){ ArrayList<Edge> list; if(!adjacencies.containsKey(source)){ list = new ArrayList<Edge>(); adjacencies.put(source, list); }else{ list = adjacencies.get(source); } list.add(new Edge(source, target, weight)); } public ArrayList<Edge> getAdjacent(Node source){ return adjacencies.get(source); } public void reverseEdge(Edge e){ adjacencies.get(e.from).remove(e); addEdge(e.to, e.from, e.weight); } public void reverseGraph(){ adjacencies = getReversedList().adjacencies; } public AdjacencyList getReversedList(){ AdjacencyList newlist = new AdjacencyList(); for(ArrayList<Edge> edges : adjacencies.values()){ for(Edge e : edges){ newlist.addEdge(e.to, e.from, e.weight); } } return newlist; } public Set<Node> getSourceNodeSet(){ return adjacencies.keySet(); } public Collection<Edge> getAllEdges(){ ArrayList<Edge> edges = new ArrayList<Edge>();

for(List<Edge> e : adjacencies.values()){ edges.addAll(e); } return edges; } } public class Edge implements Comparable<Edge> { Node from, to; int weight; Edge(Node f, Node t, int w){ from = f; to = t; weight = w; } public int compareTo(Edge e){ return weight - e.weight; } } public class Node implements Comparable<Node> { int name; boolean visited = false; // used for Kosaraju's algorithm and Edmonds's algorithm int lowlink = -1; // used for Tarjan's algorithm int index = -1; // used for Tarjan's algorithm Node(int n){ name = n; } public int compareTo(Node n){ if(n == this) return 0; return -1; } }

Dijkstra //Calcula o menor caminho entre o vrtice inicial e os outros ns de um grafo no-orientado Entrada: graph=matriz com pesos dos vrtices, initial=n inicial, end=n que se deseja saber o caminho (ou -1 para calcular de todos) Sada: na posio 0 do array retorna os caminhos mnimos para cada vrtice, posio 1 possui o caminho necessrio para chegar ao n ( um vetor, logo v[x], possui o n anterior x) Cdigo: public static Object[] dijkstra(int[][] graph, int initial, int end) {

peso[] dists = new peso[graph.length]; TreeSet<peso> h = new TreeSet<peso>(); int[] paths = new int[graph.length]; int z=0; for(int x=0;x<graph.length;x++) h.add(dists[x] = new peso(initial == x ? 0 : Double.POSITIVE_INFINITY, x)); while(!h.isEmpty()) { peso p = h.first(); if(p.peso == Double.POSITIVE_INFINITY) break; h.pollFirst(); for(int x=0;x<graph.length;x++) if(graph[p.vert][x] != 0) { double alt = p.peso + graph[p.vert][x]; if(alt < dists[x].peso) { h.remove(dists[x]); dists[x].peso = alt; paths[x] = p.vert; h.add(dists[x]); } } if(p.vert == end) break; } return new Object[]{ dists, paths }; } public static class peso implements Comparable<peso> { double peso;int vert; public peso(double p, int v){ peso = p; vert =v;} public int compareTo(peso o) { return peso < o.peso ? -1 : (peso > o.peso ? 1 : (vert < o.vert ? -1 : 1)); } }

Crivo de Erasttenes //Descobre todos os nmeros primos menores que um inteiro X Entrada: x Sada: array de nmeros primos menores que x Cdigo: public static Integer[] crivoAristotenes(int limite) { Integer[] i = new Integer[limite+1]; int max = (int)Math.floor(Math.sqrt(limite)); ArrayList<Integer> primos = new ArrayList<Integer>(); for(int x=2;x<=max;x++) if(i[x] == null) {

primos.add(x); for(int y=x+x;y<=limite;y+=x) i[y] = 0; } for(int x=max+1;x<=limite;x++) if(i[x]==null) primos.add(x); return primos.toArray(new Integer[primos.size()]); }

Convex Hull //Em C++; retorna a envoltria convexa de um conjunto de pontos Entrada: Sada: Cdigo: // Implementation of Monotone Chain Convex Hull algorithm. #include <algorithm> #include <vector> using namespace std; typedef long long CoordType; struct Point { CoordType x, y; bool operator <(const Point &p) const { return x < p.x || (x == p.x && y < p.y); } }; // 2D cross product. // Return a positive value, if OAB makes a counter-clockwise turn, // negative for clockwise turn, and zero if the points are collinear. CoordType cross(const Point &O, const Point &A, const Point &B){ return (A.x - O.x) * (B.y - O.y) - (A.y - O.y) * (B.x - O.x); } // Returns a list of points on the convex hull in counter-clockwise order. // Note: the last point in the returned list is the same as the first one. vector<Point> convexHull(vector<Point> P){ int n = P.size(), k = 0; vector<Point> H(2*n); // Sort points lexicographically sort(P.begin(), P.end()); // Build lower hull for (int i = 0; i < n; i++) { while (k >= 2 && cross(H[k-2], H[k-1], P[i]) <= 0) k--; H[k++] = P[i]; } // Build upper hull

for (int i = n-2, t = k+1; i >= 0; i--) { while (k >= t && cross(H[k-2], H[k-1], P[i]) <= 0) k--; H[k++] = P[i]; } H.resize(k); return H; }

Rotacionando valores de uma matriz Entrada: matriz que dever ser rotacionada, angulo (em grau, angulos positivos giram no sentido anti-horrio) Sada: matriz rotacionada pelo angulo Cdigo: public static int[][] rotate(int[][] m, int a) { int[][] n = new int[m.length][m.length]; double radA = Math.toRadians(a); int cosA = (int)Math.cos(radA); int sinA = (int)Math.sin(radA); int x2,y2; int med = (m.length - 1) / 2; for(int x=0;x<m.length;x++) for(int y=0;y<m.length;y++) { x2 = med + (x - med) * cosA - (y - med) * sinA; y2 = med + (x - med) * sinA + (y - med) * cosA; n[x2][y2] = m[x][y]; } return n; }

rvore de Probabilidade //Problema Vampiros Entrada: Sada: Cdigo: #include <stdio.h> #define tipo float #define precision 0.0001 tipo probabilidade=0; iterate(int A, int B, int limit, int val, tipo prob){

//

printf("A: %d B: %d prob: %f\n", A, B, prob); if (B<=0){ probabilidade += prob; return; } if (A<=0) return; if (prob > precision){ iterate(A-val, B+val, limit, val, prob*((tipo)6-limit)/6); iterate(A+val, B-val, limit, val, prob*((tipo)limit)/6); }

} int main(){ int A, B, limit, val; while(1){ scanf("%d", scanf("%d", scanf("%d", scanf("%d", &A); &B); &limit); &val);

if (A==0 && B==0 && limit==0 && val==0) return; probabilidade = 0; iterate(A, B, limit, val, 1); //printf("Probabilidade: %f\n", probabilidade*100); printf("%.1f\n", probabilidade*100); } return; } Converte DA Base 10 para K Entrada: num - inteiro na base 10 baseK - base para a qual o nmero ser convertido Sada: String que contem o num na base baseK

Cdigo: public static String convertToBase(int num, int baseK) { StringBuilder stb = new StringBuilder(); int i; while (num!=0) { i = num % baseK; stb.insert(0, (char)(i+(i>9?87:48)));

num /= baseK; } return stb.toString(); } Converte PARA a Base 10 Entrada: number - inteiro que representa o nmero que ser convertido fromBase - base na qual number est Sada: long que representa num na base 10 Observao: Horner's Algorithm -http://www.hitxp.com/math/arth/131202.htm algo que faz diferente do normal. Tenho dvidas se o overhead ao converter para string compensa a falta dos demais clculos comuns nesse tipo de converso, mas acho que sim. Cdigo: public static long convertToBase10(int number, int fromBase) { String strNum = Integer.toString(number); long num = (int)strNum.charAt(0) - 48; for (int x = 1; x < strNum.length(); x++) num = (num * fromBase) + (int)strNum.charAt(x) - 48; return num; } Truncate deixa um nmero somente com o nmero de casa especificado Entrada: f - nmero d - nmero de casas decimais Sada: nmero f com preciso de d casa decimais. Todo o resto removido, NO ARREDONDA. Cdigo: public static float truncate(float f, int d) { Double p = Math.pow(10, d); return (float)(Math.floor(f * p) / p); } Definindo Locale do Scanner e do print //Troca um inteiro de base Entrada:-Sada:-Cdigo: Scanner sc = new Scanner(System.in); sc.useLocale(Locale.ENGLISH); System.out.format(Locale.ENGLISH, "%d %s %f", inteiro, string, float); //semelhando ao printf %.3f - ARREDONDA um float para ficar com 3 casas decimais %10.3f - ARREDONDA um float para ficar com 3 casa decimais e utiliza no mnimo 10

caracteres para imprim-lo (preenche com espaco) Arrendondamento para cima s acontece em caso o nmero seguinte seja MAIOR que 5. Para nao arredondar utilizar a funcao truncate acima. float f = 1.1236f; System.out.format(Locale.ENGLISH, "%.3f", f) // "1.124" System.out.format(Locale.ENGLISH, "%10.3f", f) // " 1.124"

Converter Radianos para Graus e vice-versa Entrada:-Sada:-Cdigo: Math.toDegrees(angrad); Math.toRadians(angdeg); Simplex //Troca um inteiro de base Entrada: Sada: Cdigo:

Primo //Verifica se um nmero primo Entrada: inteiro n Sada: true ou false Cdigo: public static boolean isPrime(long n) { boolean prime = true; int limit = Math.sqrt(n); for (long i = 3; i <= limit; i += 2) if (n % i == 0) { prime = false; break; } if (( n%2 !=0 && prime && n > 2) || n == 2) { return true; } else { return false; } }

Sub Set Sum //Mochila Entrada:

Sada: Cdigo: package javaapplication1; import java.util.Arrays; public class Main { //retorna true se existe uma combinacao de elementos de //vetor de valor val //Entradas: //vetor: um vetor de inteiros ordenado //n: nmero de elementos no vetor //val: valor do peso total static boolean mochila(int vetor[], int soma[], int n, int val){ System.out.println("n: " + n + " val: " + val); if (n<=0) return false; if (val > soma[n-1]) return false; int i=n-1; while(i>-1 && vetor[i]>val) i--; if (i == -1) return false; if (vetor[i] == val) return true; boolean ret = mochila(vetor, soma, i, val-vetor[i]); if (ret) return true; else return mochila(vetor, soma, i, val); } public static void main(String[] args) { int n = 1000; int vetor[]= new int[n]; for (int i=0; i<n ; i++){ vetor[i] = (int) (Math.random() * n); } Arrays.sort(vetor); int vetorSoma[]= new int[n]; vetorSoma[0]=vetor[0]; for (int i=1; i<n ; i++){ vetorSoma[i] = vetorSoma[i-1]+vetor[i]; } for (int i=0; i<n ; i++) System.out.print(vetor[i] + " "); System.out.println();

for (int i=0; i<n ; i++) System.out.print(vetorSoma[i] + " "); System.out.println(); System.out.println("Resultado: " + mochila(vetor, vetorSoma, n, vetorSoma[n1]/2)); } }

Resolvedor de Sistemas Lineares //Resolve um sistema linear de equaes Entrada: Sada: Cdigo:

Gerador de entradas //Algoritmo gerador de grandes entradas Entrada: Sada: Cdigo:

Dijkstra //Algoritmo para o caminho mais curto Entrada: Sada: Cdigo:

Tempo //Mtodos para manipulao de tempo Entrada: Sada: Cdigo:

MDC //Mtodos para encontrar o Mximo Divisor Comum (algoritmo de euclides) Entrada: Integers x, y such that x >= y and y > 0 Sada: inteiro int gcd(int x, int y){ if (y == 0) return x; else return gcd(y, x % y); }

MMC //Mtodos para encontrar o Mnimo Divisor Comum Entrada: Sada: Cdigo: public int lcm(int a, int b){ if (a == 0 || b == 0) return 0; int index = 1; int test = a*index; while (test <= a*b) { if (test % b == 0) return test; index++; test = a * index; } return a*b; }

GEOMETRIA Operaes com retas e pontos


colineares // verifica se os pontos A, B e P so colineares Entrada: 3 pontos Sada: booleano indicando se os pontos so colineares public static boolean colineares(Ponto2D A, Ponto2D B, Ponto2D P){ double dx = B.x - A.x, dy = B.y - A.y, eps = 0.001 * (dx * dx + dy * dy); return (A.x != B.x && (A.x <= P.x && P.x <= B.x || B.x <= P.x && P.x <= A.x) || A.x == B.x && (A.y <= P.y && P.y <= B.y || B.y <= P.y && P.y <= A.y)) && Math.abs(area2(A, B, P)) < eps; }

projecao // verifica se a projeo de P no segmento AB coincide com A ou B Entrada: 3 pontos

Sada: booleano ... public static boolean projecao(Ponto2D A, Ponto2D B, Ponto2D P){ double dx = B.x - A.x, dy = B.y - A.y; double eps = 0.001 * (dx * dx + dy * dy); double len2 = dx * dx + dy * dy; double inprod = dx * (P.x - A.x) + dy * (P.y - A.y); return inprod > -eps && inprod < len2 + eps; }

projPAB // retorna a projeo do ponto P no segmento AB Entrada: 3 pontos Sada: o ponto de projeo de P no segmento AB public static Ponto2D projPAB(Ponto2D A, Ponto2D B, Ponto2D P){ double vx = B.x - A.x, vy = B.y - A.y, len2 = vx * vx + vy * vy; double inprod = vx * (P.x - A.x) + vy * (P.y - A.y); return new Ponto2D(A.x + inprod * vx/len2, A.y + inprod * vy/len2); }

projPAB // retorna a projeo do ponto P no segmento AB; usa a equao da reta : ax + by + c = 0 Entrada: os coeficientes da reta e o ponto P Sada: o ponto de projeo de P na reta de coeficientes a, b, c public static Ponto2D projPAB(double a, double b, double c, Ponto2D P){ double d = P.x * a + P.y * b + c; return new Ponto2D(P.x - d * a, P.y - d * b); }

distance2 // retorna o quadrado da distncia entre P e Q Entrada: dois pontos Sada: o quadrado da distncia entre eles public static double distance2(Ponto2D P, Ponto2D Q){ double dx = P.x - Q.x; double dy = P.y - Q.y; return dx * dx + dy * dy; }

getM // calcula o coeficiente angular da reta Entrada: dois pontos de uma reta Sada: o coeficiente angular da reta public static double getM(Ponto2D A, Ponto2D B){ return (A.y - B.y)/(A.x - B.x);

getAlpha // calcula o ngulo da reta (associado ao coeficiente angular) Entrada: dois pontos Sada: o ngulo da reta public static double getAlpha(Ponto2D A, Ponto2D B){ return Math.atan(getM(A, B)); }

lado // verifica em que lado da reta AB o ponto P est; -1 : esquerda de AB; 1 : direita de AB; 0 : pertence AB Entrada: 3 pontos Sada: inteiro indicando o lado em que o ponto se encontra public static int lado(Ponto2D A, Ponto2D B, Ponto2D P){ double s = A.x*P.y - A.y*P.x + A.y*B.x - A.x*B.y + P.x*B.y - P.y*B.x; return s<0 ? -1 : (s>0 ? 1 : 0); }

Operaes com tringulos


area2 // calcula o dobro da rea orientada de um tringulo Entrada: os 3 vrtices de um tringulo Sada: o dobro da rea orientada do tringulo - double public static double area2(Ponto2D A, Ponto2D B, Ponto2D C){ return (A.x - C.x) * (B.y - C.y) - (A.y - C.y) * (B.x - C.x); } areaTriangulo // calcula a rea de um tringulo Entrada: os 3 vrtices de um tringulo Sada: a rea do tringulo - double public static double areaTriangulo(Ponto2D A, Ponto2D B, Ponto2D C){ return Math.abs(area2(A, B, C))*0.5; }

triangulate // faz a triangulao num dado polgono; retorna a lista de triangulos encontrados Entrada: um vetor de pontos representando o polgono

Sada: uma lista de tringulos encontrados public static List<Triangulo> triangulate(Ponto2D[] pol){ int n = pol.length, j = n - 1, iA = 0, iB, iC; int[] next = new int[n]; List<Triangulo> lista = new ArrayList<Triangulo>(); for (int i=0; i<n; i++){ next[j] = i; j = i; } for (int k=0; k<n-2; k++){ Ponto2D a, b, c; boolean triaFound = false; int count = 0; while (!triaFound && ++count < n){ iB = next[iA]; iC = next[iB]; a = pol[iA]; b = pol[iB]; c = pol[iC]; if (area2(a, b, c) >= 0){ j = next[iC]; while (j != iA && !pertenceTriangulo(a, b, c, pol[j])){ j = next[j]; } if (j == iA){ lista.add(new Triangulo(a, b, c)); next[iA] = iC; triaFound = true; } } iA = next[iA]; } } return lista; }

baricentro // encontra o baricentro do tringulo Entrada: 3 pontos Sada: o baricentro do tringulo public static Ponto2D baricentro(Ponto2D A, Ponto2D B, Ponto2D C){ double x = (A.x + B.x + C.x)/3; double y = (A.y + B.y + C.y)/3; return new Ponto2D(x, y); }

Operaes com polgonos


PoligonoConvexo // verifica se um dado polgono convexo Entrada: um vetor de pontos de duas dimenses

Sada: booleano indicando se o polgono convexo public static boolean PoligonoConvexo(Ponto2D[] p){ int n = p.length,k=0; for (int i=1; i<n; i++) if (p[i].x <= p[k].x && (p[i].x < p[k].x || p[i].y < p[k].y)) k=i; int prev = k - 1, next = k + 1; if (prev == -1) prev = n - 1; if (next == n) next = 0; return area2(p[prev], p[k], p[next]) > 0; }

pertencePoligono // verifica se o ponto P pertence ao polgono Entrada: ponto P e um vetor de pontos indicando o polgono Sada: booleano indicando se o ponto pertence ao polgono public static boolean pertencePoligono(Ponto2D P, Ponto2D[] pol){ int n = pol.length, j = n - 1; boolean b = false; double x = P.x, y = P.y; for (int i=0; i<n; i++){ if (pol[j].y <= y && y < pol[i].y && areaTriangulo(pol[j], pol[i], P) > 0 || pol[i].y <= y && y < pol[j].y && areaTriangulo(pol[i], pol[j], P) > 0){ b = !b; } j = i; } return b; }

areaPoligono // calcula a area de um poligono convexo qualquer Entrada: vetor de pontos de duas dimenses Sada: a rea do poligono P - double public static double areaPoligono(Ponto2D[] pol){ int n = pol.length, j = n - 1; float a = 0; for(int i=0; i<n; i++){ a += pol[j].x * pol[i].y - pol[j].y * pol[i].x; j = i; } return a; }

Operaes com crculos e circunferncias

areaCirculo // calcula a rea de um crculo Entrada: o raio do crculo Sada: a rea do crculo public static double areaCirculo(double r){ return Math.PI*r*r; }

setorCircular // calcula a rea de um setor circular Entrada: o raio do crculo e o ngulo do setor circular Sada: a rea do setor circular public static double setorCircular(double r, double alfa){ return alfa*areaCirculo(r)/360; }

pertence // verifica se o ponto P pertence ao crculo Entrada: o centro do crculo, o raio e o ponto P Sada: booleano indicando se P pertence ao crculo public static boolean pertence(Ponto2D C, double r, Ponto2D P){ return Math.pow(P.x - C.x, 2) + Math.pow(P.y - C.y, 2) - Math.pow(r, 2) <= 0; }

interceptaCirculo // verifica se a reta que contm P e de angulo alfa intercepta o crculo de centro C e raio r Entrada: ponto P e ngulo alfa representando uma reta; ponto C e raio r representando um crculo Sada: booleano indicando se a reta intercepta o crculo public static boolean interceptaCirculo(Ponto2D P, double alfa, Ponto2D C, double r){ double tan = Math.tan(alfa); double tan2 = tan*tan; double a = 1 + tan2; double b = -2*C.x - 2*P.x*tan2 + 2*P.y*tan - 2*C.y*tan; double c = C.x*C.x + P.y*P.y + tan2*P.x*P.x + C.y*C.y - 2*P.x*P.y*tan - 2*C.y*P.y + 2*C.y*P.x*tan - r*r; return b*b - 4*a*c >= 0; }

intersecaoCirculo // retorna os pontos de interseo de uma circunferncia com uma reta Entrada: ponto P e ngulo alfa representando uma reta; ponto C e raio r representando um crculo

Sada: os pontos de interseo entre a reta e o crculo, se existirem public static Ponto2D[] intersecaoCirculo(Ponto2D P, double alfa, Ponto2D C, double r){ double tan = Math.tan(alfa); double tan2 = tan*tan; double a = 1 + tan2; double b = -2*C.x - 2*P.x*tan2 + 2*P.y*tan - 2*C.y*tan; double c = C.x*C.x + P.y*P.y + tan2*P.x*P.x + C.y*C.y - 2*P.x*P.y*tan - 2*C.y*P.y + 2*C.y*P.x*tan - r*r; double delta = b*b - 4*a*c; if(delta < 0){ return null; } else if(delta == 0){ double xt = -b/(2*a); return new Ponto2D[]{new Ponto2D(xt, P.y - tan*(P.x - xt))}; } else{ double xt1 = (-b + Math.sqrt(delta))/(2*a); double xt2 = (-b - Math.sqrt(delta))/(2*a); Ponto2D t1 = new Ponto2D(xt1, P.y - tan*(P.x - xt1)); Ponto2D t2 = new Ponto2D(xt1, P.y - tan*(P.x - xt2)); return new Ponto2D[]{t1, t2}; } }

pontosTangencia // retorna os pontos de tangncia de uma circunferncia em relao a um ponto P externo ****** no est totalmente correto ********** Entrada: ponto C e raio r representando um crculo; ponto externo P Sada: os pontos de tangncia public static Ponto2D[] pontosTangencia(Ponto2D C, double r, Ponto2D P){ double difX = (P.x - C.x)*(P.x - C.x); double difY = (P.y - C.y)*(P.y - C.y); double a = difX + difY; double b = 2*(P.x - C.x)*(C.x*C.x - C.x*P.x - r*r) - 2*C.x*difY; double c = difY*C.x*C.x + Math.pow(C.x*C.x - C.x*P.x - r*r, 2) - difY*r*r; double double double double double double double delta = b*b - 4*a*c; x1 = (-b + Math.sqrt(delta))/(2*a); x2 = (-b - Math.sqrt(delta))/(2*a); y1 = C.y + Math.sqrt(r*r - (x1 - C.x)*(x1 - C.x)); y2 = C.y - Math.sqrt(r*r - (x1 - C.x)*(x1 - C.x)); y3 = C.y + Math.sqrt(r*r - (x2 - C.x)*(x2 - C.x)); y4 = C.y - Math.sqrt(r*r - (x2 - C.x)*(x2 - C.x));

return new Ponto2D[]{new Ponto2D(x1, y1), new Ponto2D(x1, y2), new Ponto2D(x2, y3), new Ponto2D(x2,y4)}; }

Fim dos mtodos de geometria


baskara // retorna as razes de uma equao do segundo grau - no considera o caso em que delta =0 Entrada: coeficientes a, b ec Sada: um vetor contendo as razes public static double[] baskara(double a, double b, double c){ double delta = b*b - 4*a*c; if(delta >= -0.00001 || delta <= 0.00001){ return new double[]{-b/(2*a)}; } else{ return new double[]{(-b + Math.sqrt(delta))/(2*a), (-b - Math.sqrt(delta))/(2*a) }; } }

Fatorial //super otimizado Entrada: n Sada: n! static long currentN; //http://www.luschny.de/math/factorial/FastFactorialFunctions.htm public static BigInteger Factorial(int n) { if (n < 2) return BigInteger.ONE; BigInteger p = BigInteger.ONE,r = BigInteger.ONE; currentN = 1; int h = 0, shift = 0, high = 1; int log2n = (int)Math.floor(Math.log10(n) / Math.log10(2)); while (h != n) { shift += h; h = n >> log2n--; int len = high; high = (h - 1) | 1; len = (high - len) / 2; if (len > 0) { p = p.multiply(Product(len)); r = r.multiply(p); } }

return r.shiftLeft(shift); } private static BigInteger Product(int n) { int m = n / 2; if (m == 0) return BigInteger.valueOf(currentN +=2); if (n == 2) return BigInteger.valueOf((currentN += 2) * (currentN += 2)); return Product(n - m).multiply(Product(m)); } Permutao //quantos conjuntos de R elemento possvel fazer com N objetos (sem repetir objeto dentro do conjunto) Entrada: n = nmero de elementos / r = tamanho dos conjuntos Sada: nmero de conjuntos possveis public static long permutacao(int n, int r) { return Factorial(n).divide(Factorial(n -r)).longValue(); } Graham //define o envoltrio convexo em um plano 2D PASSAR PARA JAVA AINDA Entrada: n = nmero de elementos / r = tamanho dos conjuntos Sada: nmero de conjuntos possveis class Point{ public: double x,y; Point(double _x,double _y){x=_x;y=_y;}; Point(){x=0.0;y=0.0;}; }; //-----------------------------------------//indice do ponto mais baixo int get_lower_point_id(vector<Point> &in_point) { double min_y = in_point[0].y; int id_min; for(int i=0; i < in_point.size(); ++i) if(in_point[i].y < min_y ) { min_y = in_point[i].y ; id_min = i; } //cout << "id_min= " << id_min << "\n"; return id_min; }

//------------------------------------------------------------double compute_angle(double ox, double oy, double x1, double y1) { // + (x1,y1) // / // / // / // / // / angle // ------------+----------------// (ox,oy) // . // angle . . // ------------+----------------// .. \ // \ // \ // \ // \ // \ // (x1,y1) // // // double angle; x1=x1-ox; y1=y1-oy; if (y1 >=0) angle = acos(x1/(sqrt(x1*x1+y1*y1))); else angle = 2.0*PI - acos(x1/(sqrt(x1*x1+y1*y1))); //cout << angle << "x1= " << x1 << "y1= " << y1 << "x2= " << x2 << "y2= " << y2 << "\n"; return angle; } //------------------------------------------bool compute_is_left_curve(double v1x,double v1y,double v2x, double v2y, double v3x, double v3y) { //produto vetorial (v1-v2)x(v3-v2) double prod_vetorial =(v1x-v2x)*(v3y-v2y)-(v3x-v2x)*(v1y-v2y); if (prod_vetorial==0) cout<<"zero \n"; if( prod_vetorial > 0) return true; else

return false; };

//------------------------------------------typedef pair<double,int> anglepoint; void Graham(vector<Point> &in_points,vector<Point> &fecho_points) { fecho_points.clear(); int min_y_point_id = get_lower_point_id(in_points); //temos que colocar o ponto min_y_point_id na posicao zero Point temp_front_point = in_points[0]; in_points[0] = in_points[min_y_point_id]; in_points[min_y_point_id] = temp_front_point ; vector<anglepoint> list_ord; for (int i=1;i<in_points.size();++i) { //computar o ngulo entre o elemento 0 e o i-esimo elemento double angle = compute_angle(in_points[0].x, in_points[0].y, in_points[i].x,in_points[i].y); list_ord.push_back(anglepoint( angle , i ) ); } //ordenado pelo ngulo sort(list_ord.begin(), list_ord.end()); //for (int i=0; i<list_ord.size(); ++i) //cout<<"an - "<<list_ord[i].first<<"id- "<<list_ord[i].second<<"\n"; fecho_points.push_back(in_points[0]); fecho_points.push_back(in_points[list_ord[0].second]); fecho_points.push_back(in_points[list_ord[1].second]); for (int i=2;i<list_ord.size();++i) { int id = list_ord[i].second; fecho_points.push_back(in_points[id]); //testar ltimos 3 elementos da lista //else kill ate ser positivo while (!compute_is_left_curve(fecho_points[fecho_points.size()-1].x, fecho_points[fecho_points.size()-1].y, fecho_points[fecho_points.size()-2].x, fecho_points[fecho_points.size()-2].y, fecho_points[fecho_points.size()-3].x, fecho_points[fecho_points.size()-3].y) && fecho_points.size()>3 ) {

Point temp1 = fecho_points[fecho_points.size()-1]; fecho_points.pop_back(); fecho_points.pop_back(); fecho_points.push_back( temp1 ); } }

Para o dia da prova -> levar um dicionrio

Potrebbero piacerti anche