Capacitación introductoria de algoritmos de C ++: búsqueda de redes, lucha de monjes (con código)

Ejemplo: búsqueda de ruta de red

fondo del tema

        Una red en el país X utiliza varias líneas para conectar varios nodos. La comunicación entre nodos es bidireccional. Un paquete de datos importante debe reenviarse exactamente dos veces para llegar al destino por razones de seguridad. El paquete puede generarse en cualquier nodo y necesitamos saber cuántas rutas de reenvío diferentes hay en la red.

        Las direcciones de origen y destino pueden ser las mismas, pero los nodos intermedios deben ser diferentes.

        La red que se muestra en la siguiente figura.

        1 -> 2 -> 3 -> 1 están permitidos

        1 -> 2 -> 1 -> 2 o 1 -> 2 -> 3 -> 2 son ilegales.

formato de entrada

        La primera línea de los datos de entrada son dos números enteros NM, que representan respectivamente el número de nodos y el número de líneas de conexión (1<=N<=10000; 0<=M<=100000).

        Luego hay M líneas, y cada línea contiene dos números enteros u y v, lo que indica que los nodos u y v están conectados (1<=u, v<=N, u!=v).

        Los datos de entrada garantizan que dos puntos cualesquiera estén conectados como máximo por un borde y que no haya ningún borde que se conecte automáticamente, es decir, que no haya varios bordes ni bucles automáticos.

formato de salida

        Genera un número entero, que indica el número de rutas que cumplen los requisitos.

Muestras de entrada y salida

muestra de entrada

3 3 
1 2 
2 3 
1 3

muestra de salida

6

Código de referencia

#include <iostream>
#include <cstring> 
using namespace std;
 
#define MAXN 10005
#define MAXM 100005 
 
struct node{
	int to,next; 
}edge[MAXM]; 
 
int head[MAXN]; 
int cnt,sum; 
 
void add(int a,int b)
{
	node E={b,head[a]};   
	edge[cnt]=E; 
	head[a]=cnt++; 
} 
 
 
void dfs(int from,int to,int num)
{
	if (num==3)
	{ 
		sum++;  
		return;  
	}
 
	for (int i=head[to];i!=-1;i=edge[i].next)  
	{ 
		int v=edge[i].to; 
		if (v!=from)
		{  
			dfs(to,v,num+1);   
		}
	}
} 
 
int main()
{
	int n,m,a,b; 
	while (cin>>n>>m)
	{
		cnt=0;sum=0;    
		memset(head,-1,sizeof(head)); 
 
		for (int i=0;i<m;i++)
		{ 
			cin>>a>>b; 
			add(a,b); 
			add(b,a); 
		}
 
		for (int i=1;i<=n;i++)
			dfs(i,i,0); 
 
		cout<<sum<<endl; 
	}
 
	return 0; 
}


Sacar inferencias de una instancia a otros casos——Lucha de monjes eminentes

fondo del tema

        En las antiguas actividades funerarias, a menudo se invitaba a monjes eminentes a realizar rituales. Después de la ceremonia, a veces habrá un programa interesante de "Habilidades de lucha de monjes eminentes" para aliviar la atmósfera deprimida.

        Los pasos generales del programa son los siguientes: primero use grano (generalmente arroz) para "dibujar" varios pasos en el suelo (que representan pagodas de nivel N). Varios monjes jóvenes se "paran" al azar en un determinado escalón. Las personas deben pararse en el escalón más alto, y los demás son opcionales. (Como se muestra en la Figura 1)

        Los dos magos que participan en el juego le ordenan a un joven monje que suba cualquier cantidad de escalones, pero el joven monje que está parado en los escalones más altos los bloqueará y no podrán cruzar. Dos monjes jóvenes no pueden pararse en el mismo escalón, ni pueden moverse a escalones más bajos.

        Los dos magos se turnaron para dar instrucciones y, al final, todos los monjes jóvenes inevitablemente se amontonaron en los altos escalones y ya no pudieron subir. Cuando es el turno del mago para mandar y no puede continuar moviéndose, el juego termina y el mago admite la derrota.

        Para el número conocido de pasos y la posición de distribución de los monjes jóvenes, calcule cómo el mago que emitió la orden primero debe tomar una decisión para asegurar la victoria.

formato de entrada

        Los datos de entrada son una línea de N enteros separados por espacios, que indican la posición del pequeño monje. El número de pasos comienza desde 1, por lo que la posición del último pequeño monje es el número total de pasos. (N<100, número total de pasos<1000)

formato de salida

        La salida son dos números enteros separados por espacios en una línea: AB, lo que significa mover el pequeño monje en la posición A a la posición B. Si hay múltiples soluciones, genere la solución con el valor más pequeño de A y genere -1 si no hay solución.

Muestras de entrada y salida

muestra de entrada

1 5 9

muestra de salida

1 4

Código de referencia

#include <iostream>
#include <cstdio>
#include <sstream>
using namespace std;
int mp[100],sub[100],c;
int main() {
    string s;
    getline(cin,s);
    istringstream in(s);
    int t = 0;
    while(in >> mp[c ++]) {
        if(c > 1) {
            sub[c - 2] = mp[c - 1] - mp[c - 2] - 1;
            if(c % 2 == 0) t ^= sub[c - 2];
        }
    }
    if(!t) {
        printf("-1\n");
    }
    else {
        for(int i = 0;i < c - 1;i ++) {///枚举每个人
            for(int j = 1;j < mp[i + 1] - mp[i];j ++) {///移动步数
                sub[i] -= j;
                if(i) sub[i - 1] += j;

                t = 0;
                for(int k = 0;k < c - 1;k += 2) {
                    t ^= sub[k];
                }
                if(t == 0) {
                    printf("%d %d",mp[i],mp[i] + j);
                    break;
                }

                sub[i] += j;
                if(i) sub[i - 1] -= j;
            }
        }
    }
}

Supongo que te gusta

Origin blog.csdn.net/leyang0910/article/details/130713904
Recomendado
Clasificación