zoukankan      html  css  js  c++  java
  • 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 

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

    理解题意是王道。 

  • 相关阅读:
    MT【160】格点
    MT【159】单调有界有极限
    c_str() 函数
    C strstr() 函数
    全面总结:matlab怎么做漂亮的图
    程序员电邮札记
    C编译: 使用gdb调试
    C编译: 动态连接库 (.so文件)
    C编译: makefile基础
    数据科学
  • 原文地址:https://www.cnblogs.com/byluoluo/p/3463837.html
Copyright © 2011-2022 走看看