USACO Section 2.1 Sorting a Three-Valued Sequence 解题报告
题目
题目描述
给N个整数,每个整数只能是1,2,或3。现在需要对这个整数序列进行从小到大排序,问最少需要进行几次交换。N(1 <= N <= 1000)
样例输入
9
2
2
1
3
3
3
2
3
1
样例输出
4
解题思路
这个题目我没有做出来,想到一个思路,提交之后返回一个wa。后来看了一下题解,才知道自己错在什么地方。现在来回顾一下。
错误思路
我首先统计了1,2,3的个数,记为cnt1,cnt2,cnt3。然后统计在前cnt1个位置有多少个数字不是等于1的,统计在中间cnt2个位置有多少不是等于2的,统计在后面cnt3个位置有多少不是等于3的,这些统计结果分别记为tot1,tot2,tot3。然后经过一系列的神操作,我得到一个结论:tot = tot1+tot2+tot3,当tot为偶数的时候结果就是tot/2,当tot为奇数的时候结果就应该是(tot-3)/2 + 2。提交结果发现第七组样例过不了。后来想了一小会,没有找到推翻这个结论的样例,就开始找题解了。后来我根据这个思路的漏洞找到了一组样例223311,按照这个结论输出为3,其实结果是4。
正确思路
看完题解之后发现,之前找规律的时候思路不严谨,有地方没有认真证明,而是凭靠直觉解题,这是做题的大忌,得改。
首先我们同样统计出cnt1,cnt2,cnt3,然后需要统计的不是简单的tot1,tot2,tot3了,我们应该将前cnt1个位置中有多少2,有多少为3分别统计,分别记为cnt12,cnt13。同样我们要得到cnt21,cnt23,cnt31,cnt32。
第一步:我们在进行数字交换的时候如果在前cnt1个位置上发现有2,并且在中间cnt2个位置上有1,这种时候我们应该优先交换这两个数字,这样1跟2都出现在应该在的位置。然后我们看前cnt1个位置上有没有3,如果有的话应该和后面cnt3个位置上的1进行交换。同理交换所有的这样的数字。
第二步:在进行完上面的操作之后剩下的数字都是什么样的呢,如:312,这个序列,我们需要进行两次交换才能将三个数字都放在应该在的位置。所以我们得到的结论如下:
首先按照按照第一步计算需要交换的次数,然后剩下的数字都需要用第二步来交换。
解题代码
/*
ID: yinzong2
PROG: sort3
LANG: C++11
*/
#define MARK
#include <cstdio>
#include <iostream>
using namespace std;
int N;
int num[1010];
int main() {
#ifdef MARK
freopen("sort3.in", "r", stdin);
freopen("sort3.out", "w", stdout);
#endif // MARK
cin >> N;
int cnt[3] = {0};
for (int i = 0; i < N; i++) {
cin >> num[i];
cnt[num[i]-1]++;
}
int cnt12 = 0, cnt13 = 0;
for (int i = 0; i < cnt[0]; i++) {
if (num[i] == 2) {
cnt12++;
} else if (num[i] == 3) {
cnt13++;
}
}
int cnt21 = 0, cnt23 = 0;
for (int i = cnt[0]; i < cnt[0]+cnt[1]; i++) {
if (num[i] == 1) {
cnt21++;
} else if (num[i] == 3) {
cnt23++;
}
}
int cnt31 = 0, cnt32 = 0;
for (int i = cnt[0]+cnt[1]; i < cnt[0]+cnt[1]+cnt[2]; i++) {
if (num[i] == 1) {
cnt31++;
} else if (num[i] == 2) {
cnt32++;
}
}
int ans = 0;
// 第一步操作
ans += min(cnt12, cnt21); cnt12 -= min(cnt12, cnt21); cnt21 -= min(cnt12, cnt21);
ans += min(cnt13, cnt31); cnt13 -= min(cnt13, cnt31); cnt31 -= min(cnt13, cnt31);
ans += min(cnt23, cnt32); cnt23 -= min(cnt23, cnt32); cnt32 -= min(cnt23, cnt32);
// 剩下的数字需要按照第二步来操作,每个312这种序列都需要用2次交换
ans += ((cnt12 + cnt13)*2);
cout << ans << endl;
return 0;
}
USACO Section 2.1 Sorting a Three-Valued Sequence 解题报告的更多相关文章
- USACO Section 2.1 Sorting a Three-Valued Sequence
/* ID: lucien23 PROG: sort3 LANG: C++ */ #include <iostream> #include <fstream> #include ...
- USACO Section2.1 Sorting a Three-Valued Sequence 解题报告
sort3解题报告 —— icedream61 博客园(转载请注明出处)---------------------------------------------------------------- ...
- USACO Section2.2 Preface Numbering 解题报告 【icedream61】
preface解题报告----------------------------------------------------------------------------------------- ...
- USACO Section2.1 Hamming Codes 解题报告 【icedream61】
hamming解题报告----------------------------------------------------------------------------------------- ...
- USACO Section2.1 Healthy Holsteins 解题报告 【icedream61】
holstein解题报告 --------------------------------------------------------------------------------------- ...
- USACO Section2.1 The Castle 解题报告
castle解题报告 —— icedream61 博客园(转载请注明出处)--------------------------------------------------------------- ...
- USACO Section1.5 Prime Palindromes 解题报告
pprime解题报告 —— icedream61 博客园(转载请注明出处)--------------------------------------------------------------- ...
- USACO Section1.4 Mother's Milk 解题报告
milk3解题报告 —— icedream61 博客园(转载请注明出处)---------------------------------------------------------------- ...
- USACO Section1.3 Wormholes 解题报告
wormhole解题报告 —— icedream61 博客园(转载请注明出处)------------------------------------------------------------- ...
随机推荐
- 人的一生为什么要努力 &1
2018-06-25
- ccf201703-2学生排队
问题描述 体育老师小明要将自己班上的学生按顺序排队.他首先让学生按学号从小到大的顺序排成一排,学号小的排在前面,然后进行多次调整.一次调整小明可能让一位同学出队,向前或者向后移动一段距离后再插入队列. ...
- excel的宏与VBA入门(一)——基础概念
一.概述 "记录宏"其实就是将工作的一系列操作结果录制下来,并命名存储(相当于VB中一个子程序). 宏其实就是VBA写的,但是可以通过录制的方法制作宏,做好的宏你可以查看相应的VB ...
- 如何判断Android设备是否为模拟器
android.os.Build.BRAND:获取设备品牌 如果获取的Landroid/os/Build;->BRAND的值为 "generic"则为模拟器上运行. andr ...
- 论FPGA建模,与面向对象编程的相似性
很久没有写FPGA方面的博客了,因为最近一直在弄一个绘图的上位机. 我觉得自己建模思想还不错,但是面向对象思维总是晕的.突然有一天发现,两者居然有这么对共同之处,完全可以相互启发啊.就简单聊下. 1. ...
- 对*P++的理解,再联想~~~
前言: 最近在看一位叫朱有鹏大神的视频,讲的甚好.应此,我的感悟也因此被激发,准备针对朱老师将的内容,结合自己的理解,写一个系列的笔记博客--大家可以去www.zhulaoshi.org观看视频-- ...
- MFC如何为程序添加标题
1.在CMainFrame类中找到函数PreCreateWindow,在该函数中添加 cs.style &=~FWS_ADDTOTITLE;//去掉窗口的 自动标题 属性. 这句很重要不然的话 ...
- [CF1059E]Split the Tree[贪心+树上倍增]
题意 给定 \(n\) 个节点的树,点有点权 \(w\) ,划分成多条儿子到祖先的链,要求每条链点数不超过 \(L\) ,和不超过 \(S\),求最少划分成几条链. \(n\leq 10^5\) . ...
- SSRS配置1:凭证和邮件
SSRS是微软的高度集成的报表服务,通过报表服务配置管理器(Reporting Service Configuration Manager,简称RSCM),能够轻松实现报表的配置和管理,本文主要分享凭 ...
- JQuery快速入门-选择器
JQuery选择器 JQuery 选择器继承了CSS 与Path 语言的部分语法,允许通过标签名.属性名或内容对DOM 元素进行快速.准确的选择,而不必担心浏览器的兼容性,通过jQuery 选择器对页 ...