链接: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, 0, sizeof(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 }
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, 0, sizeof(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 }
--------------------------------------
理解题意是王道。