Codeforces 217div.2 C. Mittens

链接:http://codeforces.com/contest/370/problem/C

题意:有n双手袜(1<=n<=5000),每双袜子都有颜色ci(1<=c<=100),现在重新分配,问可否使每双袜子左右手颜色不同。若可以,输出一种方案;若不可以,求maximum,同样也输出一种maximum的方案。

输出格式:

第一行是n或maximum

以下每行有两个数表示手袜颜色,一个是左手的,一个是右手的 

 

思路:先求每种颜色有几双,设最大的是maxc双

若maxc>n/2,则不能令所有袜子所有手颜色不同。输出方案是,maxc的颜色选一个,其他颜色选一个,组成一双。注意一双手袜拆分成一个左手手袜,一个右手手袜,位置不一样。

最后剩余的是maxc颜色的袜子,直接输出。

若maxc<=n/2,则存在方案是每双手袜的颜色不一样。方案很多,只要保证每双手袜颜色都不同即可。

我的方法,先按颜色排序,然后首尾交换,遇到中间可能存在左右颜色一样的,就更前面已匹配的交换。

也可以先按颜色排序,然后将数组截成两份,两个数组匹配。手袜为奇数对时,有一双需要特殊处理。


 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 const int N = 5005;
 6 const int M = 105;
 7 
 8 int main()
 9 {
10     int n, m, a[M], c, maxc, ans[2*N], indexa, finalAns[2*N];
11     cin >> n >> m;
12     memset(a, 0sizeof(a));
13     maxc = 0;
14     for(int i=1; i<=n; i++)
15     {
16         cin >> c;
17         a[c] += 2;
18         if(a[maxc]<a[c]) maxc = c;
19     }
20     if(a[maxc] > n)
21     {
22         int flag = 1;
23         cout << (n - a[maxc]/2)*2 << endl;
24         for(int i=1; i<=m; i++)
25         {
26             if(maxc==i) continue;
27             while(a[i]>0)
28             {
29                 if(flag%2==1)
30                     cout << maxc << " " << i << endl;
31                 else
32                     cout << i << " " << maxc << endl;
33                 flag++;
34                 a[i]--;
35             }
36         }
37         for(int i=1; i<=n - (n - a[maxc]/2)*2; i++)
38             cout << maxc << " " << maxc << endl;
39     }
40     else
41     {
42         cout << n << endl;
43         indexa = 0;
44         for(int i=1; i<=m; i++)
45         {
46             while(a[i]>0)
47             {
48                 ans[++indexa] = i;
49                 a[i]--;
50             }
51         }
52         int flag = 1, indexfinal = 0;
53         int l = 1, r = indexa;
54         while(l<r)
55         {
56             if(flag%2==1)
57             {
58                 finalAns[l*2-2] = ans[l];
59                 finalAns[l*2-1] = ans[r];
60                 if(finalAns[l*2-2]==finalAns[l*2-1])
61                 {
62                     swap(finalAns[l*2-2],finalAns[indexfinal]);
63                     indexfinal += 2;
64                 }
65                 l++; r--;
66             }
67             else
68             {
69                 finalAns[l*2-2] = ans[r];
70                 finalAns[l*2-1] = ans[l];
71                 if(finalAns[l*2-2]==finalAns[l*2-1])
72                 {
73                     swap(finalAns[l*2-2],finalAns[indexfinal]);
74                     indexfinal += 2;
75                 }
76                 l++; r--;
77             }
78             flag++;
79         }
80         for(int i=0; i<indexa/2; i++)
81             cout << finalAns[2*i] << " " << finalAns[2*i+1] << endl;
82     }
83     return 0;
84 }
View Code 

 

 --------------------------------------

理解题意是王道。 

 

 

posted @ 2013-12-08 14:56  byluoluo  阅读(515)  评论(0编辑  收藏  举报