C++ Introductory Algorithm Training - Network Pathfinding, Monk Fighting (with code)

Example - Network Pathfinding

topic background

        A network in country X uses several lines to connect several nodes. Communication between nodes is bidirectional. An important data packet must be forwarded exactly twice to reach the destination for safety reasons. The packet may be generated at any node, and we need to know how many different forwarding paths there are in the network.

        The source and destination addresses can be the same, but the intermediate nodes must be different.

        The network shown in the figure below.

        1 -> 2 -> 3 -> 1 are allowed

        1 -> 2 -> 1 -> 2 or 1 -> 2 -> 3 -> 2 are illegal.

input format

        The first line of the input data is two integers NM, respectively representing the number of nodes and the number of connecting lines (1<=N<=10000; 0<=M<=100000).

        Then there are M lines, and each line contains two integers u and v, indicating that nodes u and v are connected (1<=u, v<=N , u!=v).

        The input data guarantees that any two points are connected by at most one edge, and there is no self-connecting edge, that is, there are no multiple edges and self-loops.

output format

        Output an integer, indicating the number of paths that meet the requirements.

Input and output samples

input sample

3 3
1 2
2 3
1 3

output sample

6

Reference Code

#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; 
}


Drawing inferences from one instance to other cases——Eminent Monk Fighting

topic background

        In ancient funeral activities, eminent monks were often invited to perform rituals. After the ceremony, sometimes there will be an interesting program of "Eminent Monk Fighting" to relieve the depressed atmosphere.

        The general steps of the program are as follows: first use grain (usually rice) to "draw" several steps on the ground (representing N-level pagodas). A number of young monks randomly "stand" on a certain step. People must stand on the highest step, and others are optional. (As shown in Figure 1)

        The two mages participating in the game command a young monk to go up any number of steps, but they will be blocked by the young monk standing on the higher steps and cannot cross. Two young monks cannot stand on the same step, nor can they move to lower steps.

        The two mages took turns giving instructions, and in the end all the young monks would inevitably be crowded on the high steps and could no longer move up. When it is the mage's turn to command and cannot continue to move, the game is over and the mage admits defeat.

        For the known number of steps and the distribution position of the young monks, please calculate how the mage who issued the order first should make a decision to ensure victory.

input format

        The input data is a line of N integers separated by spaces, indicating the position of the little monk. The number of steps starts from 1, so the position of the last little monk is the total number of steps. (N<100, total number of steps<1000)

output format

        The output is two integers separated by spaces on one line: AB, which means to move the little monk in position A to position B. If there are multiple solutions, output the solution with the smaller value of A, and output -1 if there is no solution.

Input and output samples

input sample

1 5 9 

output sample

1 4

Reference Code

#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;
            }
        }
    }
}

Guess you like

Origin blog.csdn.net/leyang0910/article/details/130713904