CCFコンピュータソフトウェアの能力の認定(CSP)問題への解決策の一部

ディレクトリ

201812から3 CIDR合併

私は与えられた最小プレフィクスリストの対象は、IPプレフィックスのプレフィックスリストの同等の数が含まれてお願いしたいと思います。

最初は、プレフィクスリストを格納する方法です。構造中にカプセル化長い長い貯蔵IPアドレス、プレフィックス長リロードと\(<ipNum、LEN> \)は、後でソート操作を容易にします。IPプレフィックスはやや分割状況を議論するために、3つの入力形式を持っています。

続いて\(ipNum \)最初のキーとして、\(LEN \)は昇順に第2の鍵です。

そして、含まれている他のIPプレフィックスのIPプレフィックスマッチングセットを削除することを検討。最後にマッチした設定範囲検討する前に\(Mmaxと\) うまくトラバーサルの順序を。リストまで、静的の存在によって、リストの残りのIPシーケンス。

最後に、隣接する組み合わせ可能IPプレフィックスの合併は、実際には、0と1の最後のビットプレフィックス長は、前とまったく同じにすることができます。

挿入や削除の操作のリストをブラッシュアップ。

#include <bits/stdc++.h>
typedef long long LL;
const int maxn = 1000000;

using namespace std;

struct tIP
{
    LL ipNum;
    int len;
    int before, next;
    tIP()
    {
        before = next = -1;
    }
    bool operator < (const tIP &y) const
    {
        if(ipNum == y.ipNum)
            return len < y.len;
        return ipNum < y.ipNum;
    }
    void show()
    {
        LL num[5];
        LL temp = ipNum;
        for (int i = 4; i >= 1; i--)
        {
            num[i] = temp % 256;
            temp /= 256;
        }
        for (int i = 1; i <=4; i++)
        {
            printf("%lld", num[i]);
            if (i == 4)
                printf("/");
            else
                printf(".");
        }
        printf("%d\n", len);
    }
};
tIP ip[maxn+10];

LL getMMax(tIP iip)
{
    LL temp = (1LL << (32-iip.len)) - 1;
    return iip.ipNum | temp;
}

int main()
{
    int n;
    scanf("%d", &n);

    char s[30];
    for (int id = 1, slash, dotCnt, style; id <= n; id++)
    {
        slash = 0;
        dotCnt = 0;
        scanf("%s", s + 1);
        for (int i = 1; s[i] != '\0'; i++)
        {
            if (s[i] == '/')
                slash = 1;
            if (s[i] == '.')
                dotCnt ++;
        }

        if (slash == 1 && dotCnt == 3)
            style = 1;
        else if (slash == 1 && dotCnt < 3)
            style = 2;
        else
            style = 3;

        LL num[5];
        memset(num, 0, sizeof(num));
        if (style == 1 || style == 2)
        {
            for (int i = 1, temp = 0, numCnt = 1; ; i++)
            {
                if (s[i] == '.' || s[i] == '/')
                {
                    num[numCnt++] = temp * 1LL;
                    temp = 0;
                }
                else if (s[i] == '\0')
                {
                    ip[id].len = temp;
                    break;
                }
                else
                {
                    temp = temp * 10 + s[i] - '0';
                }
            }
        }
        else
        {
            for (int i = 1, temp = 0, numCnt = 1; ; i++)
            {
                if (s[i] == '.')
                {
                    num[numCnt++] = temp * 1LL;
                    temp = 0;
                }
                else if (s[i] == '\0')
                {
                    num[numCnt++] = temp * 1LL;
                    ip[id].len = (numCnt-1) * 8;
                    break;
                }
                else
                {
                    temp = temp * 10 + s[i] - '0';
                }
            }
        }
        LL ans = 0;
        for (int i = 1; i <= 4; i++)
        {
            ans = ans * 256 + num[i];
        }
        ip[id].ipNum = ans;
    }

    sort(ip + 1, ip + 1 + n);

    LL mmax = -1;
    int st = 0, en = n + 1;
    ip[st].before = -1;
    ip[st].next = en;
    ip[en].before = st;
    ip[en].next = -1;
    for (int id = 1, prev = 0; id <= n; id++)
    {
        if (ip[id].ipNum > mmax)
        {
            ip[id].before = prev;
            ip[id].next = en;
            ip[prev].next = ip[en].before = id;
            prev = id;
            mmax = getMMax(ip[id]);
        }
    }

    int pNow = ip[0].next;
    while (pNow != en)
    {
        int p1 = pNow, p2 = ip[pNow].before;
        if (p2 == 0)
            pNow = ip[pNow].next;
        else
        {
            if (ip[p1].len == ip[p2].len &&
                (ip[p2].ipNum & (1LL << (32-ip[p2].len))) == 0 &&
                (ip[p2].ipNum | (1LL << (32-ip[p2].len))) == ip[p1].ipNum)
            {
                ip[p1].before = ip[p2].before;
                ip[ip[p1].before].next = p1;
                ip[p1].ipNum = ip[p2].ipNum;
                ip[p1].len --;
            }
            else
            {
                pNow = ip[pNow].next;
            }
        }
    }

    pNow = ip[0].next;
    while (pNow != en)
    {
        ip[pNow].show();
        pNow = ip[pNow].next;
    }

    return 0;
}

おすすめ

転載: www.cnblogs.com/acboyty/p/11229719.html