牛客网计算机考研复试-KY4-代理服务器

题目链接:点这里


题目描述:
使用代理服务器能够在一定程度上隐藏客户端信息,从而保护用户在互联网上的隐私。我们知道n个代理服务器的IP地址,现在要用它们去访问m个服务器。这 m 个服务器的 IP 地址和访问顺序也已经给出。系统在同一时刻只能使用一个代理服务器,并要求不能用代理服务器去访问和它 IP地址相同的服务器(不然客户端信息很有可能就会被泄露)。在这样的条件下,找到一种使用代理服务器的方案,使得代理服务器切换的次数尽可能得少。


思路:
使用贪心,每次找可以在m个 服务器中找到最远的在代理服务器中的字符串,找到后,在进行下一轮的贪心。最终得到的就是最优解。
对于这里为什么可以使用贪心,我是自己找了个例子自己想了想,在题目下面的评论看到了大佬对于使用贪心的证明,如下(原话在题目链接下的评论中)


代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 4e4;
int tes;
int fin(string ip,vector<string> a){ //在字符串数组a中二分查找字符串ip
    int l=0,r=a.size()-1;
    int mid;
    while(l<=r){
        mid = (l+r)/2;
        if(a[mid]<ip)
            l = mid+1;
        else if(a[mid]>ip)
            r = mid-1;
        else
            return mid;
    }
    return -1;
}

int main(){
    int n,m;
    int vis[1005];
    while(cin >> n && n!=EOF){
        vector<string> ip_n,ip_m;
        string s;
        for(int i=1;i<=n;i++){
            cin >> s;
            ip_n.push_back(s);
        }
        sort(ip_n.begin(),ip_n.end());
        cin >> m;
        for(int i=1;i<=m;i++){
            cin >> s;
            ip_m.push_back(s);
        }
        memset(vis,0,sizeof(vis));
        int t=0,ans = 0;
        //对n等于1时,进行特殊的判断
        if(n==1){
            for(int i=0;i<m;i++){
                if(ip_n[0]==ip_m[i])
                    ans = -1;
            }
            if(ans==-1)
                cout << -1 << endl;
            else
                cout << 0 <<endl;
            continue;
        }
        //贪心找可以走到最远的字符串,找到后ans++
        for(int i=0;i<ip_m.size();i++){
            int x = fin(ip_m[i],ip_n);
            if(x!=-1 && vis[x]==0){ //在ip_n中,并且没有被访问
                t++;
                vis[x] = 1;
            }
            if(t==n){	//表示当前可以找到了最远的字符串
                ans++;
                memset(vis,0,sizeof(vis));//初始化为0,进行下一轮的贪心
                vis[x] = 1;
                t = 1;
            }
        }
        cout << ans << endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/123-wind/p/14295810.html