zoukankan      html  css  js  c++  java
  • 九度OJ 1082:代理服务器 (DP)

    时间限制:1 秒

    内存限制:32 兆

    特殊判题:

    提交:1871

    解决:574

    题目描述:

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

    输入:

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

    样例输入:
    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
    来源:
    2009年清华大学计算机研究生机试真题

    思路:

    贪心算法,类似OS里的最优进程调度。找到后继第一次出现位置最远的代理IP,选择这个IP作为当前代理。

    用一个数组来存储当前所有选择。

    注意这个题的各种特殊情况,我WA了很多次才AC的。


    代码:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
     
    #define LEN 20
    #define N 1000
    #define M 5000
     
    int flag[N];
    int flagCount = 0;
     
    void initFlag(int n)
    {
        for (int i=0; i<n; i++)
            flag[i] = 0;
        flagCount = 0;
    }
     
    void setFlag(int i)
    {
        if (flag[i] == 0)
        {
            flag[i] = 1;
            flagCount ++;
        }
    }
     
    int cmp(const void *a, const void *b)
    {
        return strcmp((char *)a, (char *)b);
    }
     
    int main(void)
    {
        int n, m, i;
        char sn[N][LEN], sm[M][LEN];
        char *p;
        int changeCount;
     
        while (scanf("%d", &n) != EOF)
        {
            for (i=0; i<n; i++)
                scanf("%s", sn[i]);
            qsort(sn, n, sizeof(sn[0]), cmp);
     
            scanf("%d", &m);
            changeCount = 0;
            initFlag(n);
            for (i=0; i<m; i++)
                scanf("%s", sm[i]);
            for (i=0; i<m; i++)
            {
                if (flagCount == n)
                {
                    changeCount = -1;
                    break;
                }
                p = (char *)bsearch(sm[i], sn, n, sizeof(sn[0]), cmp);
                if (p == NULL)
                    continue;
                int index = (p-(char *)sn)/LEN;
                if (flag[index] == 0)
                {
                    setFlag(index);
                    if (flagCount == n)
                    {
                        changeCount ++;
                        initFlag(n);
                        setFlag(index);
                    }
                }
            }
            printf("%d
    ", changeCount);
        }
     
        return 0;
    }
    /**************************************************************
        Problem: 1082
        User: liangrx06
        Language: C
        Result: Accepted
        Time:10 ms
        Memory:964 kb
    ****************************************************************/



    别人的另一份C++ 的代码:

    #include <iostream>
    #include <vector>
    #include <string>
    #include <algorithm>
    using namespace std;
    
    int n,m;
    vector<string> a,b;
    
    int main(int argc,char* argv[]){
        //freopen("input.txt","r",stdin);
        string s;
        int n;
        while(cin>>n){
            a.resize(0);
            b.resize(0);
            while(n--){
                cin>>s;
                a.push_back(s);
            }
            cin>>m;
            while(m--){
                cin>>s;
                b.push_back(s);
            }
            if(a.size()==1&&find(b.begin(),b.end(),a[0])!=b.end()){
                cout<<"-1"<<endl;
                continue;
            }
            n = 0;
            vector<string>::iterator max = b.begin();
            vector<string>::iterator p;
            bool flag = true;
            while(flag){
                flag = false;
                max = b.begin();
                for(int i=0;i<a.size();i++){
                    p = find(b.begin(),b.end(),a[i]);
                    if(max<p){
                        max = p;
                    }
                    if(p!=b.end()){
                        flag = true;
                    }
                }
                if(max!=b.end()){
                    n++;
                }
                b.erase(b.begin(),max);
            }
            cout<<n<<endl;
        }
        return 0;
    }



    编程算法爱好者。
  • 相关阅读:
    Java开发环境搭建
    MySQL优化
    js正则表达式,验证身份证
    获取urlc参数
    Oracle解锁
    Qt 常用类 (4)—— QPoint
    Qt 常用类——QStandardItemModel
    Qt QTableWidget用法总结
    Qt 随机数
    C++ static类成员,static类成员函数
  • 原文地址:https://www.cnblogs.com/liangrx06/p/5083950.html
Copyright © 2011-2022 走看看