这道题目我一开始想错了,觉得只要排好序,再从头到尾把可以相互交换的进行下交换就可以了。。。事实证明是错的。正确的解法比较巧妙,而且写法非常好,值得学习

首先,要注意的一个规律是,假如最大的颜色数字出现的次数 为 c, c超过了n的一半,则必定无法将所有的人的颜色交换成两两不同的,而且此时颜色不同的人的数目也已经出来了

就是 (n-c)*2,于此,也很容易得出,一旦c没有超过n的一半,则肯定能够把所有人都排成不一样的,(先把相同颜色的找另一类相同颜色的互换,某一类不够了,再找另一类的来继续补充一下即可)此时的答案就是n。

进一步分析,如果是第一种情况,则一个很巧妙的处理方法就是从1到n遍历,如果当前i的颜色为颜色最多的那个颜色,则,先输出i颜色,再从非c颜色里面找不同的来匹配,当然最多只能找d个,d=n-c,如果找完d个了,就只能输出一样的颜色了,代表该人无法颜色不同。。。如果当前颜色不为i那个颜色,则先输出该颜色,再输出那个最多的颜色。

第二种情况的话,先对颜色进行排序,把相同颜色的放在一起,然后有个很巧妙的处理方法,就是某颜色的另一半=(i+c)%n.color,这个好好想想就能明白,既能遍历完整个n,又能保证不会遇到重复色(因为相同颜色在同一堆,而且这一堆的数目最大为c,所以+c再对n取模,是绝对不会匹配大到相同的颜色的)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
int date;
int id;
int other;
} p[];
bool cmp(node a,node b)
{
return a.date<b.date;
}
bool cmp2(node a,node b)
{
return a.id<b.id;
}
int c[];
int main()
{
int n,m,i,j;
while (scanf("%d%d",&n,&m)!=EOF)
{
memset(c,,sizeof c);
for (i=;i<=n;i++)
{
scanf("%d",&p[i].date);
p[i].id=i;
c[p[i].date]++; }
int maxn=,index;
for (i=;i<=m;i++)
{
if (maxn<c[i])
{
maxn=c[i];
index=i;
}
}
if (maxn*>n)
{
printf("%d\n",(n-maxn)*);
int d=n-maxn;
j=;
for (i=;i<=n;i++)
{
if (p[i].date==index)
{
printf("%d ",index);
if (d>)
{
for (j++;j<=n && p[j].date==index;j++); //这里是个细节,j每次先要++
printf("%d\n",p[j].date);
d--; }
else
printf("%d\n",index);
}
else
{
printf("%d %d\n",p[i].date,index);
}
}
}
else
{
printf("%d\n",n);
sort(p+,p++n,cmp);
for (i=;i<=n;i++)
{
int loc=i+maxn;
loc%=n;
if (loc==) loc=n;
p[i].other=p[loc].date;
}
sort(p+,p++n,cmp2);
for (i=;i<=n;i++)
{
printf("%d %d\n",p[i].date,p[i].other);
}
} }
return ; }

Codeforce 370C Mittens 巧妙数学题的更多相关文章

  1. CodeForces 370C. Mittens

    C. Mittens time limit per test 1 second memory limit per test 256 megabytes input standard input out ...

  2. 【codeforces 370C】Mittens

    [题目链接]:http://codeforces.com/problemset/problem/370/C [题意] 给你n个人,每个人都有一双相同颜色的手套; 然允许在所有人之间交换手套; (每个人 ...

  3. codeforce 375_2_b_c

    codeforce 375_2 标签: 水题 好久没有打代码,竟然一场比赛两次卡在边界条件上....跪 b.题意很简单...纯模拟就可以了,开始忘记了当字符串结束的时候也要更新两个值,所以就错了 #i ...

  4. CodeForce 855B 暴力or线段树

    CodeForce 855B 暴力or线段树 题意 给你一串数,然后找出三个数,他们的前后关系和原来一样,可以相同,然后分别乘p,q,r,求他们积的和最大,并且输出这个数. 解题思路 这个可以使用线段 ...

  5. 谈谈一些有趣的CSS题目(九)-- 巧妙的实现 CSS 斜线

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

  6. JS巧妙思路

    <script type="text/javascript"> window.onload = function () { var btn = document.get ...

  7. Ionic 的 ng-class 在聊天功能上面的巧妙运用

    很多人在问我是ionic好呢?还是react好呢? 其实我只想告诉你去看文档啊,不用用怎么知道哪个合适呢? 嘿嘿但是真的这么问的时候我也不会这么回答的,那岂不是太张狂了哈哈哈 react我确实没有用过 ...

  8. 一个巧妙的实现悬浮的tableViewHeader的方法

    之前因为工作需要要实现一个类似的 悬浮+视差的headerView的效果, 研究了好久没研究出来怎么做,最后用UICollectionView + CSStickyHeaderFlowLayout的方 ...

  9. 巧妙的重载魔术方法__call()

    工作半年了,感觉这半年学到的东西比大学四年学到的还要多,主要原因是心静下来了,目标也明确了,不会去整天的和游戏纠缠在一起了.大学时候其实也意识到了玩游戏会影响自己的正常学习和工作的,但是一直控制不了自 ...

随机推荐

  1. [Machine Learning][BP]The Vectorized Back Propagation Algorithm

    Reference: https://www.cs.swarthmore.edu/~meeden/cs81/s10/BackPropDeriv.pdf I spent nearly one hour ...

  2. 深入浅出KNN算法

    概述 K最近邻(kNN,k-NearestNeighbor)分类算法 所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表. kNN算法的核心思想是如果一个样本在特征 ...

  3. C# winform中ListView用法

    this.listView1.GridLines = true; //显示表格线 this.listView1.View = View.Details;//显示表格细节 this.listView1. ...

  4. case...when...和decode——oracle

    1.decode函数: 用法:decode(条件,值1,翻译1,值2,翻译2,......,缺省值): 例子: ','失败','未知') from table t1;--改变字段的显示值 ,变量1,变 ...

  5. C# Stream篇(五) -- MemoryStream

    MemoryStream 目录: 1 简单介绍一下MemoryStream 2 MemoryStream和FileStream的区别 3 通过部分源码深入了解下MemoryStream 4 分析Mem ...

  6. P 1027 打印沙漏

    转跳点:

  7. Dubbo与SpringCloud

    dubbo和springcloud都是微服务框架,各自有各自的注册中心. dubbo监控中心:zookeeper,redis 提供高性能和透明化的RPC远程调用方案,SOA服务治理方案. 核心部分: ...

  8. 当DIV内出现滚动条,fixed实效怎么办?

    sticky    盒位置根据正常流计算(这称为正常流动中的位置),然后相对于该元素在流中的 flow root(BFC)和 containing block(最近的块级祖先元素)定位.在所有情况下( ...

  9. 第三章,数据和C

    3.1 数据类型关键字 位:计算机内部数据存储的最小存储单位(bit). 字节:计算机中数据处理的基本单位(Byte)),1B=8bit. 字:计算机进行数据处理时,一次存取,加工和传送的数据长度.( ...

  10. Android自定义View——简单实现边缘凹凸电子票效果

        View继承LinearLayout,在View的上下边缘画出白色的圆形即可,这里只要计算出圆的个数和圆的循环规律即可,下面请看分析 我们取卡片的前2个凹凸来看,将其分为四部分,并且两部分为循 ...