题目

题目描述

给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 解题报告的更多相关文章

  1. USACO Section 2.1 Sorting a Three-Valued Sequence

    /* ID: lucien23 PROG: sort3 LANG: C++ */ #include <iostream> #include <fstream> #include ...

  2. USACO Section2.1 Sorting a Three-Valued Sequence 解题报告

    sort3解题报告 —— icedream61 博客园(转载请注明出处)---------------------------------------------------------------- ...

  3. USACO Section2.2 Preface Numbering 解题报告 【icedream61】

    preface解题报告----------------------------------------------------------------------------------------- ...

  4. USACO Section2.1 Hamming Codes 解题报告 【icedream61】

    hamming解题报告----------------------------------------------------------------------------------------- ...

  5. USACO Section2.1 Healthy Holsteins 解题报告 【icedream61】

    holstein解题报告 --------------------------------------------------------------------------------------- ...

  6. USACO Section2.1 The Castle 解题报告

    castle解题报告 —— icedream61 博客园(转载请注明出处)--------------------------------------------------------------- ...

  7. USACO Section1.5 Prime Palindromes 解题报告

    pprime解题报告 —— icedream61 博客园(转载请注明出处)--------------------------------------------------------------- ...

  8. USACO Section1.4 Mother's Milk 解题报告

    milk3解题报告 —— icedream61 博客园(转载请注明出处)---------------------------------------------------------------- ...

  9. USACO Section1.3 Wormholes 解题报告

    wormhole解题报告 —— icedream61 博客园(转载请注明出处)------------------------------------------------------------- ...

随机推荐

  1. 使用redis

    通过 Nuget获取包StackExchange.Redis 写数据: ConnectionMultiplexer redis = ConnectionMultiplexer.Connect(&quo ...

  2. go语言之行--结构体(struct)详解、链表

    一.struct简介 go语言中没有像类的概念,但是可以通过结构体struct实现oop(面向对象编程).struct的成员(也叫属性或字段)可以是任何类型,如普通类型.复合类型.函数.map.int ...

  3. angular-ui-router速学

    Demo1 初始化 <html ng-app="app"> <head> <style>.active { color: red; font-w ...

  4. [CF986F]Oppa Funcan Style Remastered[exgcd+同余最短路]

    题意 给你 \(n\) 和 \(k\) ,问能否用 \(k\) 的所有 \(>1\) 的因子凑出 \(n\) .多组数据,但保证不同的 \(k\) 不超过 50 个. \(n\leq 10^{1 ...

  5. 浅谈android Service和BroadCastReceiver

    1.题记 Android中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序. 广播接收者(BroadcastRece ...

  6. C#_Stream

    IO操作基本上需要用到Stream相关的子类,因此这类问题在CSDN问得也是比较多.其实对于Stream来说,操作起来比较简单,只要对细节的处理稍微注意一下,相信在使用它的时候也会得心应手. 对于St ...

  7. Js_Eval方法

    定义和用法eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码. 语法eval(string) 其中参数string为必需.是要计算的字符串,其中含有要计算的 JavaScr ...

  8. mount命令详解及常见问题汇总

    一 .mount命令(用来挂载硬盘或镜像等) 用法:mount [-t vfstype] [-o options] device dir1.-t vfstype 指定文件系统的类型,通常不必指定.mo ...

  9. IT简历

    对很多IT毕业生来说,写简历投简历是必不可少的.一个好的简历已是面试成功的一半. 简历的目的是为了引人注意,争取让HR主动联系你去面试,不可避免的在简历中掺杂着一些水分,但是能争取到面试机会,再与HR ...

  10. 面向 Kubernetes 编程: Kubernetes 是下一代操作系统

    转自:https://github.com/answer1991/articles/blob/master/Kubernetes-is-the-next-generation-os.md 摘要 此文章 ...