Codeforce 370C Mittens 巧妙数学题
这道题目我一开始想错了,觉得只要排好序,再从头到尾把可以相互交换的进行下交换就可以了。。。事实证明是错的。正确的解法比较巧妙,而且写法非常好,值得学习
首先,要注意的一个规律是,假如最大的颜色数字出现的次数 为 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 巧妙数学题的更多相关文章
- CodeForces 370C. Mittens
C. Mittens time limit per test 1 second memory limit per test 256 megabytes input standard input out ...
- 【codeforces 370C】Mittens
[题目链接]:http://codeforces.com/problemset/problem/370/C [题意] 给你n个人,每个人都有一双相同颜色的手套; 然允许在所有人之间交换手套; (每个人 ...
- codeforce 375_2_b_c
codeforce 375_2 标签: 水题 好久没有打代码,竟然一场比赛两次卡在边界条件上....跪 b.题意很简单...纯模拟就可以了,开始忘记了当字符串结束的时候也要更新两个值,所以就错了 #i ...
- CodeForce 855B 暴力or线段树
CodeForce 855B 暴力or线段树 题意 给你一串数,然后找出三个数,他们的前后关系和原来一样,可以相同,然后分别乘p,q,r,求他们积的和最大,并且输出这个数. 解题思路 这个可以使用线段 ...
- 谈谈一些有趣的CSS题目(九)-- 巧妙的实现 CSS 斜线
开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...
- JS巧妙思路
<script type="text/javascript"> window.onload = function () { var btn = document.get ...
- Ionic 的 ng-class 在聊天功能上面的巧妙运用
很多人在问我是ionic好呢?还是react好呢? 其实我只想告诉你去看文档啊,不用用怎么知道哪个合适呢? 嘿嘿但是真的这么问的时候我也不会这么回答的,那岂不是太张狂了哈哈哈 react我确实没有用过 ...
- 一个巧妙的实现悬浮的tableViewHeader的方法
之前因为工作需要要实现一个类似的 悬浮+视差的headerView的效果, 研究了好久没研究出来怎么做,最后用UICollectionView + CSStickyHeaderFlowLayout的方 ...
- 巧妙的重载魔术方法__call()
工作半年了,感觉这半年学到的东西比大学四年学到的还要多,主要原因是心静下来了,目标也明确了,不会去整天的和游戏纠缠在一起了.大学时候其实也意识到了玩游戏会影响自己的正常学习和工作的,但是一直控制不了自 ...
随机推荐
- [Machine Learning][BP]The Vectorized Back Propagation Algorithm
Reference: https://www.cs.swarthmore.edu/~meeden/cs81/s10/BackPropDeriv.pdf I spent nearly one hour ...
- 深入浅出KNN算法
概述 K最近邻(kNN,k-NearestNeighbor)分类算法 所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表. kNN算法的核心思想是如果一个样本在特征 ...
- C# winform中ListView用法
this.listView1.GridLines = true; //显示表格线 this.listView1.View = View.Details;//显示表格细节 this.listView1. ...
- case...when...和decode——oracle
1.decode函数: 用法:decode(条件,值1,翻译1,值2,翻译2,......,缺省值): 例子: ','失败','未知') from table t1;--改变字段的显示值 ,变量1,变 ...
- C# Stream篇(五) -- MemoryStream
MemoryStream 目录: 1 简单介绍一下MemoryStream 2 MemoryStream和FileStream的区别 3 通过部分源码深入了解下MemoryStream 4 分析Mem ...
- P 1027 打印沙漏
转跳点:
- Dubbo与SpringCloud
dubbo和springcloud都是微服务框架,各自有各自的注册中心. dubbo监控中心:zookeeper,redis 提供高性能和透明化的RPC远程调用方案,SOA服务治理方案. 核心部分: ...
- 当DIV内出现滚动条,fixed实效怎么办?
sticky 盒位置根据正常流计算(这称为正常流动中的位置),然后相对于该元素在流中的 flow root(BFC)和 containing block(最近的块级祖先元素)定位.在所有情况下( ...
- 第三章,数据和C
3.1 数据类型关键字 位:计算机内部数据存储的最小存储单位(bit). 字节:计算机中数据处理的基本单位(Byte)),1B=8bit. 字:计算机进行数据处理时,一次存取,加工和传送的数据长度.( ...
- Android自定义View——简单实现边缘凹凸电子票效果
View继承LinearLayout,在View的上下边缘画出白色的圆形即可,这里只要计算出圆的个数和圆的循环规律即可,下面请看分析 我们取卡片的前2个凹凸来看,将其分为四部分,并且两部分为循 ...