1. 程式人生 > >Problem I. International Collegiate Routing ContestGym

Problem I. International Collegiate Routing ContestGym

題目意思是,說給予n個32位IP地址,每個地址的後面有一個K,每個K代表與當前所給的IP地址的前K位相同的話,就為同一IP地址,然後問你,最少再補充多少的IP地址使得能構成所有的IP地址。

 思路:字典樹的題目,對於每個32位的串,輸入字典樹中,如果當前K小於32那麼就只匯入到第K位,然後在當前節點做標記,建完樹後,跑一遍DFS就可以了。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node{
    int next[2];
    int v;
    void init(){
        v=0;
        memset(next,-1,sizeof(next));
    }
};
struct node L[4000000];
int tot=0;

void add(char a[],int len, int x){
    int now=0;
    for(int i=0;i<len;i++){
        int tmp=a[i]-'0';
        int next=L[now].next[tmp];
        if (i + 1 == x) {
        	L[now].next[tmp] = -2;
        	return;
        }
        if (next == -2) {
        	return;
        }
        if(next==-1){
            next=++tot;
            L[next].v=-1;
            L[next].init();
            L[now].next[tmp]=next;
        }

        now=next;
        L[now].v++;
    }

}

int T, n;
int a,b,c,d,k;
char s[50];
int  becom_cha(int x, int len)
{
	int l = len;
	int r = len;
	for (int i = 0; i < 7; i++) {
		s[r++] = x%2 + '0';
		x = x/2;
	}
	s[r++] = x+'0';
	reverse(s+l, s+r);
	return r;
}
struct point{
	long long int x, y;
	point (long long int a = 0, long long int b = 0) {
		x = a;
		y = b;
	}
};
int a1[100];
vector<point> q;

void dfs(int now, long long int x, int len)
{
	if (len == 32) return;
	for (int i = 0; i < 2; i++) {
		
		if (L[now].next[i] == -2) continue;
		else if (L[now].next[i] == -1) {
			long long int ans = 2*x+i;
			for (int j = len+1; j < 32; j++) {
				ans = 2 * ans;	
			}
			q.push_back(point(ans, len+1));
		}
		else dfs(L[now].next[i], x*2+i, len+1);
	}
	return;
}

int main()
{
	scanf("%d", &T);
	int cas = 0;
	while (T--) {
		cas++;
		scanf("%d", &n);
		tot = 0;
		L[tot].init();
		if (n == 0) {
			printf("Case #%d:\n1\n0.0.0.0/0\n", cas);
			continue;

		}
		for (int i = 1; i <= n; i++) {
			int len = 0;
			scanf("%d.%d.%d.%d", &a, &b, &c, &d);
			char ch=getchar();
			if(ch=='/')	scanf("%d",&k);
			else k=0;
			len = becom_cha(a, len);
			len = becom_cha(b, len);
			len = becom_cha(c, len);
			len = becom_cha(d, len);
			add(s, len, k);
		}
		q.clear();
		dfs(0, 0, 0);
		printf("Case #%d:\n", cas);
		if(k==0){
			printf("0\n");
			continue;
		}
		printf("%d\n",q.size());
		for (int i = 0; i < q.size(); i++) {
			long long int ans = q[i].x;
			for (int j = 0; j < 3; j++) {
				a1[j] = ans%256;
				ans /= 256;
			}
			a1[3] = ans;
			for (int j = 3; j >= 0; j--) {
				printf("%d%c", a1[j],j==0?'/':'.');
			}
			printf("%lld\n", q[i].y);
		}

	}
}