KY4 Proxy Server

Posted by hermand on Mon, 07 Feb 2022 18:29:14 +0100

describe

The use of proxy servers can hide client information to some extent, thus protecting users'privacy on the Internet. We know the IP addresses of n proxy servers and now use them to access m servers. The IP address and access order of the M servers are also given. The system can only use one proxy server at a time and requires that it cannot use a proxy server to access the same server as its IP address (otherwise, client information may be compromised). Under such circumstances, find a solution to use proxy server so that proxy server switches as few times as possible.

Enter a description:

Each test data includes n + m + 2 rows. Line 1 contains only one integer n, representing the number of proxy servers. Lines 2 through n + 1 each contain a string representing the IP address of the proxy server. The n IP addresses are different. Line n + 2 contains only one integer m, indicating the number of servers to access. Lines n + 3 to n + m + 2 are strings each representing the IP addresses of the servers to be accessed, given in the order in which they are accessed. Each string is a legitimate IP address in the form of "xxx.yyy.zzz.www", any part of which is an integer between 0 and 255. No line of input data contains space characters. Among them, 1<=n<=1000 and 1<=m<=5000.

Output description:

There may be multiple sets of test data. For each set of input data, the output data has only one row and contains an integer s, which represents the minimum number of times a proxy server is switched during required access to the server. The proxy server used for the first time does not count in the number of switches. Output-1 if no arrangement meets the requirements.

Example 1

Input:

3
166.111.4.100
162.105.131.113
202.112.128.69
6
72.14.235.104
166.111.4.100
207.46.19.190
202.112.128.69
162.105.131.113
118.214.226.52

Output:

1

Ideas

Greedy: When accessing server servers in turn, access as many proxies as possible at once (that is, access as many servers) and switch proxies.

  • Server servers are accessed in turn, and proxies are marked when they encounter one proxy A. All proxies are considered to have been previously accessed with this proxy A.
  • Switch the proxy (number of times + 1) and clear the flags other than A. Then iterate through servers, again, mark the proxy until all proxies are marked when a proxy B is encountered, which is assumed to have been previously accessed with that proxy B.
  • Switch agents (times + 1), and so on...

Special case: If there is only one proxy and the proxy appears in the sequence of servers to be accessed, there is no solution that meets the requirements, and -1 is returned.

Code

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n = 0, m = 0;
    vector<string> agents;//proxy server
    vector<string> servers;//Server to access
    int res = -1;
    string ip = "";
    while(cin >> n){
        for(int i = 0; i < n; i++){
            cin >> ip;
            agents.push_back(ip);
        }
        cin >> m;
        for(int i = 0; i < m; i++){
            cin >> ip;
            servers.push_back(ip);
        }
        /*
        Greedy: Access server servers in turn, and mark proxies when they encounter them.
        All agents are marked until they encounter a proxy A, which is considered to have been previously accessed by the proxy A.
        
        Switch the proxy (number of times + 1) and clear any flags other than A. Similarly, when you encounter proxy flags,
        All agents are marked until they encounter a proxy B, which is considered to have been previously accessed by that proxy B.
        
        Switch agents (times + 1), and so on...
        */
        res = 0;
        bool* flag = (bool*)malloc(sizeof(bool)*agents.size());//Tag Array
        for(int i = 0; i < agents.size(); i++)
            flag[i] = false;
        for(int i = 0; i < servers.size(); i++){
            if(res == -1)break;
            
            for(int j = 0; j < agents.size(); j++){
                if(servers[i] == agents[j]){//The server to access is a proxy server
                    if(agents.size() == 1){//No solution meets the requirements
                        res = -1;
                        break;
                    }
                    flag[j] = true;
                    //Check if proxy is marked all
                    bool is = true;
                    for(int k = 0; k < agents.size(); k++)
                        if(flag[k] == false){
                            is = false;
                            break;
                        }
                    if(!is)break;//Agent is not marked entirely
                    res++;//Proxy marked all, switch proxy
                    for(int k = 0; k < agents.size(); k++)//Reset Tag Array
                        flag[k] = false;
                    flag[j] = true;
                    break;
                }
            }
        }
        cout << res << endl;
        free(flag);
    }
    return 0;
}

Topics: C++ greedy algorithm