题目链接:点这里
题目描述:
使用代理服务器能够在一定程度上隐藏客户端信息,从而保护用户在互联网上的隐私。我们知道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;
}