Codeforces Round #217 (diy.2) C. Mittens

题目链接:点击打开链接


1、先将输入的不同颜色按照该颜色出现频率排序得到左边的。

2、再把该颜色序列重新排序-----即从出现频率第二大的颜色移动到与上面那个序列第一个匹配。

       得到右边的。

3、统计左右不同的数量。


吐槽1:

我极度极度无语的是用GNU C++ 4.7 提交总是WA在第38组数据上。

换了MS C++ (Microsoft Visual C++2010)后就AC了。。。

前后两种写法都能AC!!!!!!!!冤死!!!!


吐槽2:

题目根本就没说左边的序列要和原来保持一致啊。。。。

我开始写的代码WA在第一组的原因就是左边的序列要和原来保持一致= =。。。。我不知道这么多人怎么就

知道作者的意图1Y了。。。


官方题解:

Let’s show that if the most frequent color appears not more than  times, than all children can get mittens of distinct colors. One way to construct such solution is to sort all left mittens in the order of decreasing frequency of their colors: for the input 1 2 1 2 3 1 3 3 1 we get 1 1 1 1 3 3 3 2 2. To obtain the sequence of right mittens, rotate the sequence of left mittens to the left by the maximum color frequency (in the example it is 4, so we get the sequence 3 3 3 2 2 1 1 1 1). Then just match the sequences (1 — 3, 1 — 3, 1 — 3, 1 — 2, 3 — 2, 3 — 1, 3 — 1, 2 — 1, 2 — 1). It can be easily shown that all pairs consist of distinct colors.

OK, but what to do if there is a dominating color that appears more than half times? Use exactly the same algorithm! It will maximize the number of pairs of distinct colors.


#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<algorithm>
#include<vector>
#include<cmath>
#include<cstdlib>
#include<cctype>
using namespace std;

struct node
{
    int id,cnt;
}c[110];

bool cmp(node a,node b)
{
    return a.cnt>=b.cnt;
}

int l[5010],r[5010];

int main()
{
    int n,m,x;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(c,0,sizeof(c));

        for(int i=0;i<n;i++)
        {
            scanf("%d",&x);
            c[x].cnt++;
            c[x].id=x;
        }
        sort(c+1,c+m+1,cmp);

        int r1=0,r2=0,ans=0;
        for(int i=1;i<=m;i++)
        {
            for(int j=0;j<c[i].cnt;j++)
            {
                l[r1++]=c[i].id;
            }
        }
        for(int i=2;i<=m;i++)
        {
            ans+=c[i].cnt;
            for(int j=0;j<c[i].cnt;j++)
            {
                r[r2++]=c[i].id;
            }
        }
        for(int k=0;k<c[1].cnt;k++)
        {
            r[r2]=c[1].id;
            if(r[r2]!=l[r2])
                ans++;
            r2++;
        }
        /*for(int i=0;i<n;i++)
        {
            if(l[i]!=r[i])
                ans++;
        }*/
        printf("%d\n",ans);
        for(int i=0;i<n;i++)
            printf("%d %d\n",l[i],r[i]);
    }
    return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<algorithm>
#include<vector>
#include<cmath>
#include<cstdlib>
#include<cctype>
using namespace std;

struct node
{
    int id,cnt;
}c[110];

bool cmp(node a,node b)
{
    return a.cnt>=b.cnt;
}

int l[5010],r[5010];

int main()
{
    int n,m,x;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(c,0,sizeof(c));

        for(int i=0;i<n;i++)
        {
            scanf("%d",&x);
            c[x].cnt++;
            c[x].id=x;
        }
        sort(c+1,c+m+1,cmp);

        int r1=0,r2=0,ans=0;
        for(int i=1;i<=m;i++)
        {
            for(int j=0;j<c[i].cnt;j++)
            {
                l[r1++]=c[i].id;
            }
        }
        for(int i=2;i<=m;i++)
        {
            //ans+=c[i].cnt;
            for(int j=0;j<c[i].cnt;j++)
            {
                r[r2++]=c[i].id;
            }
        }
        for(int k=0;k<c[1].cnt;k++)
        {
            r[r2]=c[1].id;
           // if(r[r2]!=l[r2])
            //    ans++;
            r2++;
        }
        for(int i=0;i<n;i++)
        {
            if(l[i]!=r[i])
                ans++;
        }
        printf("%d\n",ans);
        for(int i=0;i<n;i++)
            printf("%d %d\n",l[i],r[i]);
    }
    return 0;
}


WA在第一组的代码:

错误原因:wrong answer The multiset of left colors is not the same as original.


#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<algorithm>
#include<vector>
#include<cmath>
#include<cstdlib>
#include<cctype>
using namespace std;

struct node
{
    int id;
    int cnt;
}c[110];

int d[110];

bool cmp(node a,node b)
{
    return a.cnt>=b.cnt;
}

int main()
{
    int n,m,x;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(c,0,sizeof(c));
        for(int i=0;i<n;i++)
        {
            scanf("%d",&x);
            c[x].cnt++;
            c[x].id=x;
        }

        sort(c,c+m+1,cmp);
        for(int i=0;i<m;i++)
            c[i].cnt=2*c[i].cnt;

        int ans=0;

        for(int i=0;i<m;i++)
        {
            d[i]=c[i].cnt;
        }
        int i=0,j=m-1;
        while(i<j)
        {
            if(d[i])
            {
                while(d[i] && i<j)
                {
                    ans+=d[j];
                    j--;
                    d[i]-=d[j];
                }
            }
            else
                i++;
        }

        printf("%d\n",ans);
        int r=0,s=m-1;

        for(int i=0;i<n;i++)
        {
            if(c[r].cnt && c[s].cnt)
            {
                printf("%d %d\n",c[r].id,c[s].id);
                c[r].cnt--;
                c[s].cnt--;
            }
            if(c[r].cnt==0)
                r++;
            if(c[s].cnt==0)
                s--;
        }
    }
    return 0;
}


不能吐槽更多!!!!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值