oj : 代理服务器

2 篇文章 0 订阅
1 篇文章 0 订阅

输入描述:

    每个测试数据包括 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);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值