输入描述:
每个测试数据包括 n + m + 2 行。 第 1 行只包含一个整数 n,表示代理服务器的个数。 第 2行至第n + 1行每行是一个字符串,表示代理服务器的 IP地址。这n个 IP地址两两不相同。 第 n + 2 行只包含一个整数 m,表示要访问的服务器的个数。 第 n + 3 行至第 n + m + 2 行每行是一个字符串,表示要访问的服务器的 IP 地址,按照访问的顺序给出。 每个字符串都是合法的IP地址,形式为“xxx.yyy.zzz.www”,其中任何一部分均是0–255之间的整数。输入数据的任何一行都不包含空格字符。 其中,1<=n<=1000,1<=m<=5000。
输出描述:
可能有多组测试数据,对于每组输入数据, 输出数据只有一行,包含一个整数s,表示按照要求访问服务器的过程中切换代理服务器的最少次数。第一次使用的代理服务器不计入切换次数中。若没有符合要求的安排方式,则输出-1。
示例1
输入
复制
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
输出
复制
1
解题思路:
1. 举个例子
如果 server : 1 2
ip 序列 : 1 3 4 5 6 2
那么可知 我们只需要一开始选择2即可最大化使用一个server
所以 遍历整个ip序列 server 第一次全部出现的时候 此时必须要换一次server了
最后一次出现的server 即是我们一开始就选用的server 它让我们直接不切换的情况下 访问到了包含server完整序列的ip子序列
然后 再以最后出现的 server为开始 继续寻找下一个完整序列止点 以此类推即是切换次数
需要注意的是
如 server 为 a b
第一次 递推 a 1 2 b a 3 4
此种情况 我们到 b 需要切换第一次 由b切换为a 然后b后紧接着一个a 我们此时又需要切换
所以 序列是从b开始 再次计算下一个完整出现的序列 而不是 从b的下一个元素计算下一个出现的完整序列。
另外就是 -1的输出 当且仅当server 只有一个的时候可能存在这种-1的情况 如果sever仅有一个 且ip序列中存在与server一样的ip地址则输出-1 否则不存在-1的情况
#include<cstdio>
#include<string>
#include<iostream>
#include<map>
using namespace std;
map<string,int> mp;
int main(){
int n,m;
int i = 0;
int sum = 0;
int round = 0;
int se_count = 0;
while(scanf("%d",&n)!=EOF){
i = 0;
sum = 0;
round = 0;
se_count = 0;
string server[n];
for(int j=0;j<n;j++){
cin >> server[j];
mp[server[j]] = 0;
}
scanf("%d",&m);
string ip[m];
for(int j=0;j<m;j++) cin >> ip[j];
while(i<m){
if( mp.find(ip[i])==mp.end()){
i++;
continue;
}else{
//cout << round << ' ' << ip[i] << ' ' << mp[ip[i]] << '\n';
if(mp[ip[i]] == round){
if(n==1&&ip[i]==server[0]){
sum = -1;
break;
}
se_count ++;
mp[ip[i]]++;
if(se_count == n){
mp[ip[i]]++;
se_count = 1;
sum++;
round++;
//printf("turn\n");
}
}
}
i++;
}
printf("%d\n",sum);
}
}