elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado:


  Mostrar Mensajes
Páginas: 1 2 3 4 5 6 7 8 9 10 [11] 12 13 14 15 16 17 18 19 20 21 22 23 24
101  Programación / Programación C/C++ / Re: Leer de la entrada estandar linea por linea en: 6 Julio 2010, 01:14 am
No me había fijado que había puesto C, sin STL lo que he dicho como que no xDD.

Por si te sirve de ayuda, te dejo un código del algoritmo de Dinic que tenía hecho, sigue el formato de entrada y salida de este problema:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=10&page=show_problem&problem=761

Código
  1. /****************************************************************************************/
  2. /* Algoritmo Dinic (usa blocking flows en lugar de caminos aumentativos) Coste: O(V^2E) */
  3. /****************************************************************************************/
  4.  
  5. #include <iostream>
  6. #include <string.h>
  7. using namespace std;
  8.  
  9. //Cambiar constantes si es necesario
  10. #define NODOS 100
  11. const int INF = 1000000000;
  12.  
  13. int adj[NODOS][NODOS], deg[NODOS], cap[NODOS][NODOS], padre[NODOS], f[NODOS][NODOS], MC[NODOS], visto[NODOS];
  14. int n, m; // n = |V|, m = |E|
  15.  
  16. int Q[NODOS]; //cola
  17. int ebp, esp;
  18.  
  19. bool bfs(int s, int t) {
  20.    esp = ebp = 0;
  21.    memset(padre, -1, sizeof(padre));
  22.    memset(visto, 0, sizeof(visto));
  23.    visto[s] = 1;
  24.    padre[s] = -2;
  25.    Q[esp++] = s;
  26.    while (ebp != esp) {
  27.        int u = Q[ebp++];
  28.        for (int i = 0; i < deg[u]; ++i) {
  29.            int v = adj[u][i];
  30.            if (cap[u][v] - f[u][v] > 0 and not visto[v]) {
  31.                visto[v] = 1;
  32.                padre[v] = u;
  33.                Q[esp++] = v;
  34.            }
  35.        }
  36.    }
  37.    return visto[t];
  38. }
  39.  
  40. void mincut(int s) {
  41.    ebp = esp = 0;
  42.    Q[esp++] = s;
  43.    MC[s] = 1;
  44.    while (ebp != esp) {
  45.        int u = Q[ebp++];
  46.        for (int i = 0; i < deg[u]; ++i) {
  47.            int v = adj[u][i];
  48.            if (cap[u][v] - f[u][v] > 0 and not MC[v]) {
  49.                MC[v] = 1;
  50.                Q[esp++] = v;
  51.            }
  52.        }
  53.    }
  54. }
  55.  
  56. int maxflow(int s, int t) {
  57.    int flow = 0;
  58.    memset(MC, 0, sizeof(MC));
  59.    memset(f, 0, sizeof(f));
  60.    while (bfs(s, t)) {
  61.        for (int i = 0; i < n; ++i) {
  62.            if (cap[i][t] - f[i][t] > 0 and padre[i] != -1) {
  63.                int bot = cap[i][t] - f[i][t];
  64.                for (int v = i, u = padre[i]; u >= 0; v = u, u = padre[u])
  65.                    bot = min(bot, cap[u][v] - f[u][v]);
  66.                if (bot == 0) continue;
  67.                f[i][t] += bot;
  68.                f[t][i] -= bot;
  69.                for (int v = i, u = padre[i]; u >= 0; v = u, u = padre[u]) {
  70.                    f[u][v] += bot;
  71.                    f[v][u] -= bot;
  72.                }
  73.                flow += bot;
  74.            }
  75.        }
  76.    }
  77.    mincut(s); //MC[u] == 1 <=> u esta en la particion de s
  78.    return flow;
  79. }
  80.  
  81. int main() {
  82.    int net = 1;
  83.    while (cin >> n and n > 0) {
  84.        memset(deg, 0, sizeof(deg));
  85.        memset(cap, 0, sizeof(cap));
  86.        int s, t;
  87.        cin >> s >> t >> m;
  88.        s--; t--;
  89.        for (int i = 0; i < m; ++i) {
  90.            int a, b, c;
  91.            cin >> a >> b >> c;
  92.            --a; --b;
  93.            if (cap[a][b] == 0) {
  94.                adj[a][deg[a]++] = b;
  95.                adj[b][deg[b]++] = a;
  96.            }
  97.            cap[a][b] += c;
  98.            cap[b][a] += c;
  99.        }
  100.        cout << "Network " << net++ << endl;
  101.        cout << "The bandwidth is " << maxflow(s,t) << "." << endl << endl;
  102.    }
  103. }
102  Programación / Programación C/C++ / Re: Leer de la entrada estandar linea por linea en: 6 Julio 2010, 00:56 am
Puedes leer una línea entera usando
Código
  1. getline(cin,s);
Donde s es una string.

Luego para parsear la entrada, si sabes que siempre serán números, puedes usar stringstream e ir leyendo desde s y añadiendo en un vector los números. Si no, deberías picar alguna función que compruebe que si es número o no.

En referencia al algoritmo, ¿cuál usas para calcular el Maxflow?
103  Programación / Programación General / Re: Programa para hallar números amigos en: 27 Junio 2010, 19:10 pm
Bueno, ante todo no conozco Fortran ni lo he usado nunca, pero en tu código, no tendrías que poner a 0 las variables s y t para cada nuevo valor de n?

Otra cosa, por lo que veo, tú quieres encontrar los números amigos en un intervalo [n,m] y en tu código lo que haces es iterar sobre el valor de n y lo comparas con m, que la dejas fija. Así, suponiendo que lo que te he dicho arriba esté bien, sólo miras si m es amigo de algún número dentro del intervalo, pero si el intervalo es [30,50], no miras nunca si 34 es amigo de 42, por poner un ejemplo.

Una forma de corregir el algoritmo sería hacer lo siguiente (te lo pongo en pseudocódigo):
Código:
i := n;
mientras i <= m
    s := suma_divisores(i);
    si s > i y s <= m
        t := suma_divisores(s);
        si t = i
            imprime i " y " s " son amigos";
        fsi
    fsi
    i := i + 1;
fsi
Con este algoritmo, la complejidad es del orden de O(n2) puesto que tal y como tú calculas los divisores necesitas otro bucle lineal para cada número. En C++, el código quedaría así más o menos (no lo he probado):
Código
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. int suma_div(int n) {
  5.    int s = 0;
  6.    for (int i = 1; i <= n/2; ++i) if (n%i == 0) s += i;
  7.    return s;
  8. }
  9.  
  10. int main() {
  11.    int n, m;
  12.    cin >> n >> m;
  13.    for (int i = n; i <= m; ++i) {
  14.        int s = suma_div(i);
  15.        if (s > i and s <= m and suma_div(s) == i) cout << i << " y " << s << " son amigos" << endl;
  16.    }
  17. }
Para mejorar la eficiencia, podrías hacer una Criba de Eratóstenes al inicio del código para calcular todos los primos hasta la raíz cuadrada de m y luego para calcular los divisores, factorizar con dichos primos el número y generar con un pequeño bactracking todos los divisores, pero aunque supongo que iría más rápido, el código sería un poco más largo.
104  Programación / Ejercicios / Re: Practiquemos C++ (juntos) en: 19 Febrero 2010, 19:13 pm
Bueno, pues uno muy típico. Dadas dos strings, decir la longitud de la máxima subsecuencia que tengan en común (subsecuencia != substring). Hacedlo con una complejidad temporal polinómica, nada de probar a saco todas las posibilidades.

Un saludo de ghastlyX ;)
105  Programación / Ejercicios / Re: Practiquemos C++ (juntos) en: 19 Febrero 2010, 18:51 pm
Si te he entendido, es un simple backtracking muy sencillo de hacer.
Código
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <string>
  4. using namespace std;
  5.  
  6. void rec(int p, string& s, string r) {
  7.    if (p == s.size()) {
  8.        do {
  9.            cout << r << endl;
  10.        } while (next_permutation(r.begin(), r.end()));
  11.        return;
  12.    }
  13.    rec(p + 1, s, r);
  14.    r.push_back(s[p]);
  15.    rec(p + 1, s, r);
  16. }
  17.  
  18. int main() {
  19.    string s;
  20.    cin >> s;
  21.    sort(s.begin(), s.end());
  22.    rec(0, s, "");
  23. }

Un saludo de ghastlyX ;)
106  Programación / Ejercicios / Re: Ejercicio: las posibles combinaciones de una lista [python] en: 4 Septiembre 2009, 17:58 pm
Supongo que os referís a mostrar los subconjuntos de k elementos dada una lista de n elementos. He hecho un código en C++ que hace eso:
Código
  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4.  
  5. typedef vector<int> VI;
  6. typedef vector<bool> VB;
  7.  
  8. void rec(VI& v, VB& usado, int cnt, int primero, int n) {
  9.    if (cnt == n) {
  10.        cout << "{";
  11.        bool first = true;
  12.        for (int i = 0; i < usado.size(); ++i) {
  13.            if (usado[i]) {
  14.                if (first) first = false;
  15.                else cout << ",";
  16.                cout << v[i];
  17.            }
  18.        }
  19.        cout << "}" << endl;
  20.        return;
  21.    }
  22.    for (int i = primero; i < v.size(); ++i) {
  23.        usado[i] = true;
  24.        rec(v, usado, cnt + 1, i + 1, n);
  25.        usado[i] = false;
  26.    }
  27. }
  28.  
  29. int main() {
  30.    int n;
  31.    cin >> n; //numero de elementos;
  32.    VI v(n);
  33.    for (int i = 0; i < n; ++i) cin >> v[i];
  34.    for (int i = 0; i <= n; ++i) {
  35.        cout << "Subconjuntos de " << i << " elementos:" << endl;
  36.        VB usado(n, false);
  37.        rec(v, usado, 0, 0, i); //genera los subconjuntos de v de i elementos (habra n sobre i)
  38.        cout << endl;
  39.    }
  40. }
  41.  

Un saludo de ghastlyX ;)
107  Programación / Ejercicios / Re: Algoritmia-Ejercicios introductorios. en: 21 Junio 2009, 20:36 pm
Para el 3, pongo varios algoritmos de ordenación en C++ que permiten ordenar un vector de reales:

Ordenación por inserción (O(n2)):
Código
  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4.  
  5. void ordena_por_insercion(vector<double>& v) {
  6.    for (int i = 1; i < v.size(); ++i) {
  7.        double x = v[i];
  8.        int j = i;
  9.        while (j > 0 and v[j-1]>x) {
  10.            v[j] = v[j-1];
  11.            --j;
  12.        }
  13.        v[j] = x;
  14.    }
  15. }


Ordenación por selección (O(n2)):
Código
  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4.  
  5. int posicion_maximo(const vector<double>& v, int n) {
  6.    int pos = 0;
  7.    for (int i = 1; i <= n; ++i)
  8.        if (v[i] > v[pos]) pos = i;
  9.    return pos;
  10. }
  11.  
  12. void ordena_por_seleccion(vector<double>& v, int n) {
  13.    if (n > 0) {
  14.        swap(v[posicion_maximo(v,n)],v[n]);
  15.        ordena_por_seleccion(v,n-1);
  16.    }
  17. }

Ordenación por burbuja (O(n2)):
Código
  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4.  
  5. void ordena_por_burbuja(vector<double>& v) {
  6.    for (int i = 0; i < v.size(); ++i) {
  7.        for (int j = v.size()-1; j >= i + 1; --j) {
  8.            if (v[j] < v[j - 1] ) swap(v[j], v[j - 1]);
  9.        }
  10.    }
  11. }

Y un par de algoritmos Divide&Conquer, primero Merge Sort (Ordenación por fusión, O(n log n)):
Código
  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4.  
  5. void fusiona(vector<double>& v, int e, int m, int d) {
  6.    int n = d-e+1;
  7.    vector<double> aux (n);
  8.  
  9.    int i = e;
  10.    int j = m + 1;
  11.    int k = 0;
  12.    while (i <= m and j <= d) {
  13.        if (v[i] <= v[j]) {
  14.            aux[k] = v[i];
  15.            ++i;
  16.            ++k;
  17.        }
  18.        else {
  19.            aux[k] = v[j];
  20.            ++j;
  21.            ++k;
  22.        }
  23.    }
  24.    while (i <= m) {
  25.        aux[k] = v[i];
  26.        ++k;
  27.        ++i;
  28.    }
  29.  
  30.    while (j <= d) {
  31.        aux[k] = v[j];
  32.        ++j;
  33.        ++k;
  34.    }
  35.    for (k = 0; k < n; ++k) v[k+e] = aux[k];
  36. }
  37.  
  38. void ordena_rec(vector<double>& v, int e, int d) {
  39.    if (e < d) {
  40.        int m = (e+d)/2;
  41.  
  42.        ordena_rec(v,e,m);
  43.        ordena_rec(v,m+1,d);
  44.        fusiona(v,e,m,d);
  45.    }
  46. }
  47.  
  48. void ordena_por_fusion(vector<double>& v) {
  49.    ordena_rec(v, 0, v.size()-1);
  50. }

Otro Divide&Conquer, Quicksort (O(n log n) en caso promedio, O(n2) en el peor caso, aunque en general es más rápido que el Merge Sort):
Código
  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4.  
  5. int pivota(vector<double>& v, int ini, int fin) {
  6.    double valor_pivote = v[ini];
  7.    int p1 = ini + 1, p2 = fin - 1;
  8.    while (p1 <= p2) {
  9.        if (v[p1] < valor_pivote) ++p1;
  10. else if (v[p2] >= valor_pivote) --p2;
  11. else {
  12.    swap(v[p1], v[p2]);
  13.    ++p1;
  14.    --p2;
  15. }
  16.    }
  17.    swap(v[ini], v[p1 - 1]);
  18.    return p1 - 1;
  19. }
  20.  
  21. void quicksort_rec(vector<double>& v, int ini, int fin) {
  22.    if (ini >= fin - 1) return;
  23.    int pivote = pivota(v, ini, fin);
  24.    quicksort_rec(v, ini, pivote);
  25.    quicksort_rec(v, pivote + 1, fin);
  26. }
  27.  
  28. void quicksort(vector<double>& v, int r) {
  29.    quicksort_rec(v, 0, r);
  30. }

Un saludo de ghastlyX ;)
108  Programación / Ejercicios / Re: Ejercicios con arrays en: 5 Junio 2009, 01:13 am
Si he entendido bien el enunciado, así es bastante más sencillo:
Código
  1. #include <iostream>
  2. #include <queue>
  3. #include <vector>
  4. using namespace std;
  5.  
  6. int main() {
  7.    queue<int> Q;
  8.    vector<int> cantidad(12, 0);
  9.    int a;
  10.    bool acabado;
  11.    while (not acabado) {
  12.        cout << "Ingresa una carta" << endl;
  13.        cin >> a;
  14.        acabado = (++cantidad[a - 1] == 3);
  15.        Q.push(a);
  16.    }
  17.    cout << "Secuencia" << endl;
  18.    while (not Q.empty()) {
  19.        cout << Q.front() << " ";
  20.        Q.pop();
  21.    }
  22.    cout << endl;
  23. }

Un saludo de ghastlyX ;)
109  Programación / Ejercicios / Re: Ejercicios Básicos en: 24 Mayo 2009, 02:33 am
Sí, así te ahorras tener que pasar por cada uno de los cuadrados. Habría que decidir si el cero es o no es cuadrado perfecto. Si lo consideras cuadrado perfecto, sería el bucle hasta K - 1 incluído, si no empezaría en 1 y sería hasta K.

Un saludo de ghastlyX ;)
110  Programación / Ejercicios / Re: Ejercicios Básicos en: 24 Mayo 2009, 02:10 am
Este código no es muy eficiente...

Sabemos que un número tiene un número impar de divisores si y sólo si es un cuadrado perfecto.

En vez de ir número a número y ver si es un cuadrado, es más fácil directamente coger los k primeros números y mostrar sus cuadrados. Como yo digo haces k iteraciones, como tú haces estás mirando hasta el último de los cuadrados perfectos, es decir, k2 iteraciones.

Un saludo de ghastlyX ;)
Páginas: 1 2 3 4 5 6 7 8 9 10 [11] 12 13 14 15 16 17 18 19 20 21 22 23 24
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines