1. 程式人生 > >滴滴出行程式設計題兩道

滴滴出行程式設計題兩道

[程式設計題] CIDR去重

時間限制:1秒

空間限制:65536K

無類別域間路由(CIDR)是一個用於對IPV4地址進行分類表述的方法。CIDR 路由描述的IP地址組的子網mask長度是可變長度, 例如10.0.0.0/22 表示前22位和10.0.0.0相同的網路地址都被覆蓋, 22包含了10.0這前兩個欄位(0-7位,8-15位)和第三個欄位的前6位(16-21,即0b000000**), 涵蓋了 10.0.0.*, 10.0.1.*, 10.0.2.*, 10.0.3.* 四組ip地址. 在此前提下請實現IP網路中的一個常用的去重操作: 給定一系列 CIDR 路由地址, 其中沒有完全等價的路由, 去掉被重複表示的 CIDR 路由, 即去掉已經被其他CIDR路由表示覆蓋的路由地址. 例如 10.0.1.1/32 已經被 10.0.0.0/22覆蓋了, 如果路由列表中已經有了後者, 就可以去掉前者. 

輸入描述:

k+1行, k表示輸入的CIDR路由個數
第1行:表示路由個數k
第2~k+1行: 表示一個CIDR路由, 形如 x.x.x.x/x

輸出描述:

n+1行, n表示去重後剩下的CIDR路由個數
第1行:n
第2~n+1行: 表示一個去重後的CIDR路由, 輸出按照輸入順序

輸入例子1:

13
192.168.0.0/16
172.24.96.17/32
172.50.137.225/32
202.139.219.192/32
172.24.68.0/24
192.183.125.71/32
201.45.111.138/32
192.168.59.211/32
192.168.26.13/32
172.24.0.0/17
172.24.5.1/32
172.24.68.37/32
172.24.168.32/32

輸出例子1:

7
192.168.0.0/16
172.50.137.225/32
202.139.219.192/32
192.183.125.71/32
201.45.111.138/32
172.24.0.0/17
172.24.168.32/32
#include<bits/stdc++.h>
using namespace std;

struct ipaddr{
    string ip;
    string front;
    bool hided; 
    ipaddr() {ip = front = ""; hided = false;}
};

int str2num(string str) {
    int res = 0;
    for (char c : str) {
        res *= 10;
        res += c - '0';
    }
    return res;
}

void divide(ipaddr a, int arr[]) {
    string tmpstr;
    int len = a.ip.length();
    int i, j, cnt = 0;
    for (i = 0; i < len; ++i) {
	tmpstr = "";
        tmpstr += a.ip[i];
        for (j = i + 1; j < len && a.ip[j] != '.'; ++j) {
            tmpstr += a.ip[j];
        }
        arr[cnt++] = str2num(tmpstr);
        i = j;
    }
}

string dec2bin(int n) {
    string res;
     if (n == 0) {
	res = "00000000";
	}
    while (n) {
        res += n % 2 + '0';
        n /= 2;
    }
    for (int i = res.length(); i < 8; ++i) {
	res += '0';
    }
    reverse(res.begin(), res.end());
    return res;
}

int ishided(ipaddr a, ipaddr b) {
    int arrofa[4], arrofb[4];
    int frontofa, frontofb;
    divide(a, arrofa);
    frontofa = str2num(a.front);
    divide(b, arrofb);
    frontofb = str2num(b.front);
    string astr, bstr, aa, bb;
    astr = dec2bin(arrofa[0]) + dec2bin(arrofa[1]) 
            + dec2bin(arrofa[2]) + dec2bin(arrofa[3]);
    bstr = dec2bin(arrofb[0]) + dec2bin(arrofb[1]) 
            + dec2bin(arrofb[2]) + dec2bin(arrofb[3]);
    aa = astr.substr(0, frontofa);
    bb = bstr.substr(0, frontofb);
    int len = min(frontofa , frontofb);
    int i;
    for (i = 0; i < len; ++i) {
        if (aa[i] != bb[i])
            break;
    }
    if (i == len) {
	if (frontofa < frontofb)
	return 1;
	if (frontofa > frontofb)
	return -1;
    }
    return 0;//no hide
}

int rmdulp(ipaddr arr[], int k) {
    int n = k;
    int hide = 0;
    for (int i = 0; i < k; ++i) {
	if (arr[i].hided)
		continue;
        for (int j = i + 1; j < k; ++j) {
            if (arr[j].hided) {
                continue;
            }
		hide = ishided(arr[i], arr[j]);
            if (hide == 1) { 
                arr[j].hided = true;
                n--;
	    } else if (hide == -1) {
		arr[i].hided = true;
		n--;
	    }
        }
    }
    return n;
}

int main() {
    int k, n, npos;
    cin >> k;
    string s;
    ipaddr arr[k];
    for (int i = 0; i < k; ++i) {
        cin >> s;
        npos = s.find('/');
        arr[i].ip = s.substr(0, npos);
        arr[i].front = s.substr(npos + 1);
    }
    cout << rmdulp(arr, k) << endl;
    for (int i = 0; i < k; ++i) {
        if (!arr[i].hided) {
            cout << arr[i].ip << '/' << arr[i].front << endl;
        }
    }
    return 0;
}

[程式設計題] 冪運算

時間限制:1秒

空間限制:131072K

給定兩個數R和n,輸出R的n次方,其中0.0<R<99.999, 0<n<=25

輸入描述:

多組測試用例,請參考例題的輸入處理 輸入每行一個浮點數 R 其中0.0 < R <99.999, 一個整數 n 其中0 < n <=25

輸出描述:

輸出R的n次方

輸入例子1:

95.123 12 0.1 1

輸出例子1:

548815620517731830194541.899025343415715973535967221869852721 0.1
//取整 冪運算 除10的冪次方
#include<bits/stdc++.h>
using namespace std;

string addstr(string a, string b) {
    int lena = a.length();
    int lenb = b.length();
    int i, j, tmp, addbit = 0;
    string res;
    for (i = j = 0; i < lena || j < lenb; ++i, ++j) {
	tmp = 0;
	if (i < lena) {
        	tmp = a[i] - '0';
	} 
	if (j < lenb) {
		tmp += b[i] - '0';
	}
	tmp += addbit;
        addbit = tmp / 10;
        res += tmp % 10 + '0';
    }
    if (addbit) {
	res += '1';
    }
    return res;
}

string multistr(string a, string b) {
    int i, j, tmp, addbit = 0;
    int lena = a.length();
    int lenb = b.length();
    string tmpstr, res = "0";
    for (i = lena - 1; i >= 0; --i) {
	for (j = 1; j < lena - i; ++j)
		tmpstr += '0';
        for (j = lenb - 1; j >= 0; --j) {
            tmp = (a[i] - '0') * (b[j] - '0') + addbit;
            addbit = tmp / 10;
            tmpstr += tmp % 10 + '0';
        }
	if (addbit) {
		tmpstr += addbit + '0';
	}
	addbit = 0;
        res = addstr(res, tmpstr);
        tmpstr = "";
    }
    reverse(res.begin(), res.end());
    return res;
}

string spown(string s, int n) {
   string res = s;
   for (int i = 1; i < n; ++i) {
	res = multistr(res, s);
    }
    return res;
}

int main() {
    string r;
    int i, n;
    cin >> r >> n;
    int len = r.length();
    int npos = r.find('.');
    int div = 0;
    string s;
    if (npos > -1) {
	for (i = len - 1; i > npos; --i) {
		if (r[i] != '0') 
			break;
	}
	r = r.substr(0, i + 1);
        s = r.substr(0, npos);
        s += r.substr(npos + 1);
        s = spown(s, n);
	div = i - npos;
	int slen = s.length();
	if (slen <= n) {
		cout << "0.";
		for (i = 0; i < n - slen; ++i)
			cout << '0';
        	cout << s << endl;
	} else {
		cout << s.substr(0, slen - div * n) << ".";
		cout << s.substr(slen - div * n) << endl; 
	}
    } else {
        s = r;
	s = spown(s, n) ;
        cout << s << endl;
    }	
    return 0;
}