给N个字符串分组,
第一行输入N(0<N<=100000),接下来N行每行给出两个字符串(0<名字长度<=20),表示该两个字符串为一组
输出最多的组数
最讨厌这种乍一看很简单结果越写越难的题了。。。两种方法的核心都是先判断两个字符串是否已经存在在一个小组内,如果两个在同一个小组,则do nothing;如果在不同的小组,则合并小组;如果只有一个在小组内,则直接把另一个字符串添加进该小组;否则就新建一个小组。
方法一:用vector<set>记录</set>
#include <bits/stdc++.h> using namespace std; int main() { int N; cin>>N; string a,b; vector< set<string> > record; for(int i=0;i<N;i++){ cin>>a; cin.get(); cin>>b; cin.get(); //cout<<a<<" "<<b<<endl; bool done_flag=false; for(int i=0;i<record.size() && !done_flag;i++){ if(record[i].find(a) != record[i].end() || record[i].find(b) != record[i].end()){ if(record[i].find(a) != record[i].end() && record[i].find(b) != record[i].end()){ done_flag=true; break; } if(record[i].find(b) != record[i].end()) swap(a,b); for(int j=i+1;j<record.size();j++){ if(record[j].find(b) != record[j].end()){ record[i].insert(record[j].begin(),record[j].end()); record.erase(record.begin()+ j); done_flag=true; break; } } } } if(!done_flag){ set<string> tmp; tmp.insert(a);tmp.insert(b); record.push_back(tmp); } } cout<<record.size()<<endl; return 0; }
方法二:链表
#include <bits/stdc++.h> using namespace std; /* 定义了一个链表用来存一个组的结点,用set来维护不同的小组 每次得到一对新的字符串,遍历set中每条链表的每个结点 只要其中一个字符串已经存在于某结点: 继续遍历该链表,如果另一个结点也存在其中,则完成 如果另一个字符串不在相同链表中,则继续遍历剩下的链表: 如果在剩下的链表中找到该字符串,则将这条链表移动到第一条链表后面,并删除原来的链表 如果找不到,则直接将另一个字符串添加到第一条链表后面。 如果两个字符串都不在所有链表中,则新建两个节点,加入set中。 最后set的size就是小组的数量。 */ struct ListNode{ string name; ListNode* next; ListNode* pre; }; ListNode* nullptr = new ListNode();//可以注释掉,我的编译器不支持c++11 int main() { int N; cin>>N; string a,b; set<ListNode*> record; for(int i=0;i<N;i++){ cin>>a; cin.get(); cin>>b; cin.get(); //cout<<a<<" "<<b<<endl; set<ListNode*>::iterator itor; int done_flag=-1;//-1表示未完成, 1表示已经完成 for(itor = record.begin();itor!=record.end() && done_flag==-1 ;itor++){ ListNode* node = *itor; ListNode* tail = nullptr;//记录第一条链表的尾部 while(node != nullptr && done_flag!=1 ){ if(node->name==a || node->name==b){//找到其中一个字符串 if(node->name == b && done_flag==-1) swap(a,b);//使b为剩下的字符串 //这条路径下是否有b节点 while(node != nullptr){ if(node ->name == b) { done_flag=1; break; } if(node->next == nullptr) tail = node; node = node->next; } if(done_flag==1) break; //这条路径下没有b节点 for(itor++; itor!=record.end() && done_flag!= 1;itor++){//继续遍历剩下的链表 ListNode* tmp_node = *itor; ListNode* tmp_head = *itor; while(tmp_node != nullptr){ if(tmp_node->name == b){//找到了b字符串 tail -> next = tmp_head; tmp_head->pre = tail; record.erase(tmp_head); done_flag = 1; break; } tmp_node = tmp_node->next; } } if(done_flag != 1){//没有找到b字符串,新建节点添加到a所在链表的尾部 ListNode* n = new ListNode(); tail->next= n; n->name = b; n->pre = tail; n->next = nullptr; done_flag = 1; } } node = node->next; } } if(itor == record.end() && (done_flag==-1)){ ListNode* n1 = new ListNode(); ListNode* n2 = new ListNode(); n1->name = a; n2->name = b; n1->next = n2; n1->pre = nullptr; n2->pre = n1; n2->next = nullptr; record.insert(n1); } } cout<<record.size()<<endl; return 0; }