UVa10763 交换学生

题目描述:题目大意是有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\n";
26         else cout << "NO\n";
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\n";
21         else cout << "YES\n";
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]--;        
}

  

posted @ 2019-07-30 21:38  patrolli  阅读(317)  评论(0编辑  收藏  举报