题目描述:题目大意是有n个学生想交换到其他学校学习,规定每一个想从A交换到B的学生必须有一个想从B到A的学生与之配对,才能进行交换。最后如果每个人都能找到配对的学生,那么交换可以进行,输出YES,反之输出NO。
思路:
1. 因为从A到B的学生可以有多个,以及也可以有从A到C的情况,所以不能用map来保存数据。于是我用multiple来保存每组数据,在每次输入新的(A,B)后,都检查此前的multimap中是否出现(B,A)的一组数据,如果找到就将这两组数据都删除,在处理完所有输入后,如果multiple为空,那么这N个人刚好可以全部配对,输出YES,否则输出NO。这里需要积累一下multiple的一些操作。
1 int main() 2 { 3 int n; 4 multimap<int, int> ms; 5 // freopen("uva10763_in.txt", "r", stdin); 6 // freopen("uva10763_out.txt", "w", stdout); 7 while(cin >> n && n){ 8 int a, b; 9 while(n--){ 10 cin >> a >> b; 11 multimap<int, int>::iterator tmp = ms.insert(pair<int, int>(a,b)); //保存刚进入的位置 12 if(int k = ms.count(b)){ 13 multimap<int, int>::iterator it = ms.find(b); 14 while(k){ 15 if(it->second == a){ //找到配对的一对就删除这一对 16 ms.erase(it); 17 ms.erase(tmp); 18 break; 19 } 20 ++it; 21 --k; 22 } 23 } 24 } 25 if(ms.empty()) cout << "YES "; 26 else cout << "NO "; 27 ms.clear(); 28 } 29 }
2. 上面这个方法提交上去耗时1100ms。。。于是在网上找了下别人的做法,果然在耗时和实现上都远远好于上面这个方法。。所以都将其记录下来,一点一点学习。
其实多想一步,只要将(A,B)的每个A和每个B都分别用数组保存下来,然后分别将两个数组排序,最后如果两个数组完全一样,那么能够完全配对,否则不可以。
1 int main() 2 { 3 int n; 4 vector<int> sa, sb; 5 while(cin >> n && n){ 6 int a, b; 7 int flag = 0; 8 while(n--){ 9 cin >> a >> b; 10 sa.push_back(a); 11 sb.push_back(b); 12 } 13 sort(sa.begin(), sa.end()); 14 sort(sb.begin(), sb.end()); 15 for(int i = 0; i < sa.size(); ++i){ 16 if(sa[i] != sb[i]){ 17 flag = 1; 18 } 19 } 20 if(flag) cout << "NO "; 21 else cout << "YES "; 22 sa.clear(); 23 sb.clear(); 24 } 25 return 0; 26 }
3. 此外还有一种方法,就是直接统计每个学校想出去和想进来的人数,最后处理完输入后,如果每个学校的出入人数刚好抵消,那么就是YES。
map<int, int> all; while(N--){ scanf("%d%d", a, b); all[a]++; all[b]--; }