Sicily 1027 MJ, Nowhere to Hide

题目太长就不粘了。
一. 题意理解
有 2N 行输入,每行包括一个 ID 和一个 IP,一个人可以有两个ID,但他的 IP 是固定且唯一的。第一次出现的ID是主ID, 第二次出现的 ID是主 ID 的 MaJia。要求输出MJ关系。
给出输入和输出:
Sample Input
8
inkfish 192.168.29.24 (1)
zhi 192.168.29.235 (2)
magicpig 192.168.50.170 (3)
pegasus 192.168.29.235 (2)
iamcs 202.116.77.131 (4)
finalBob 192.168.29.24 (1)
tomek 202.116.77.131 (4)
magicduck 192.168.50.170 (3)
4
mmmmmm 172.16.72.126 (1)
kkkkkk 192.168.49.161 (2)
llllll 192.168.49.161 (2)
nnnnnn 172.16.72.126 (1)
0

Sample Output
tomek is the MaJia of iamcs
finalBob is the MaJia of inkfish
magicduck is the MaJia of magicpig
pegasus is the MaJia of zhi

llllll is the MaJia of kkkkkk
nnnnnn is the MaJia of mmmmmm
以第一组输入为例,inkfish是第一次出现的ID,IP是192.168.29.24。这个IP还出现了一次,此时ID为
finalBob,那么就说finalBob是inkfish的MaJia。题目对输出还有一个要求,即主ID以字典序排列。比如说第一组输出,iamcs<inkfish<magicpig<zhi。

二. 解题思路
我们发现ID和IP具有很强的对应关系,而且都是string,所以可以考虑使用map。关于map的使用,这篇博客介绍得很详细。
利用 map 的对应的特点,map 的 first 和 second 都是string。我认为这题麻烦的地方在于需要按照字典序输出,因此我采用了两个map,分别为 m1 和 m2。m1用来存储ID和IP的关系,m2用来存储主ID和MJID的关系。
我们可以在输入时以 IP 作为 m1 的first,以主 ID 作为 m1 的 second。如果一个 IP 已经出现过(用库函数 count 判断),说明这个 ID 是 MJ,那么将这个IP的主 ID 作为 m2 的first,将第 MJ 作为 m2 的 second(建立这种对应关系,是为了对主ID 排序完毕之后便于输出)。

三. 代码实现

#include<iostream>
#include<map>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;

int main() {
	int n;
	while (cin >> n && n != 0) {
		map<string, string> m1;
		map<string, string> m2;
		vector<string> tmp;
		string str1, str2;
		for (int i = 0; i < n; i++) {
			cin >> str1 >> str2;
			if (m1.count(str2)) {  //输入的IP已经出现过
				m2[m1[str2]] = str1;  //m1[str2]是第一次出现的ID
				tmp.push_back(m1[str2]);  //主ID存入tmp,便于排序
			}
			else m1[str2] = str1;  //输入的IP没出现过,存入m1中
		}
		sort(tmp.begin(), tmp.end());   //将主ID排序
		for (int i = 0; i < tmp.size(); i++) {
			cout << m2[tmp[i]] << " is the MaJia of " << tmp[i] << endl;
		}
		cout << endl;
	}
	
	return 0;
}

四. 总结与心得
本题的难点在于按照字典序输出。输入的每一行中 ID 和 IP 的对应关系很适合使用 map,理解了 map 的功能不难想到解决办法。时间复杂度分析:使用了 count 函数,时间复杂度为O(n*log(n)*L),其中 L 为字符串的最大长度。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值