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 博客园(转载请注明出处)------------------------------------------------------------- ... 
随机推荐
- VB6 CHECK is run as  admin privilege
			vb6 code: Private Declare Function IsUserAnAdmin Lib "Shell32" Alias "#680" () A ... 
- 20155237 《JAVA程序设计》实验三(敏捷开发与XP实践)实验报告
			20155237 <JAVA程序设计>实验三(敏捷开发与XP实践)实验报告 实验内容 敏捷开发与XP实践 XP基础 XP核心实践 相关工具 实验要求 1.没有Linux基础的同学建议先学习 ... 
- # 20155319 Exp3 免杀原理与实践
			20155319 Exp3 免杀原理与实践 基础问题 (1)杀软是如何检测出恶意代码的? 基于特征码的检测 启发式的恶意软件检测 基于行为的恶意软件检测 (2)免杀是做什么? 免杀,从字面进行理解,避 ... 
- 【WPF】两则动画效果
			原文:[WPF]两则动画效果 引言 利用WPF的动画可以轻而易举的实现各种各样的特效,如擦除,滑动进入等,先看两个效果图 第一个效果 这个动画其实利用了OpacityMask和LinearGradie ... 
- sql查询语句示例
			今天没事又专门学习了一下sql查询语句,个人感觉太重要了,于是就找了网上的一个示例自己练了起来,感觉学到了很多,下面跟大家分享一下sql查询语句的示例操作. 首先,我建了5张表,分别如下: (a)学生 ... 
- noi.ac 257 B
			链接 题目 区间[l,r]是连续满足,[l,r]中的数字的权值区间是一段连续的.多次询问可以完包含一个区间的连续区间.区间长度尽量小,如果有多个输出左端点靠左的. 分析: [l,r]区间是连续的,当且 ... 
- idea 设置格式化代码 快捷键
- laraver框架学习
			最近开始学习laravel框架,这个框架在国外很流行,近些年开始在国内流行.自己而是刚开始学习这个框架. 使用composer 更新系统内的依赖包 在终端输入:composer update Entr ... 
- ESLint 规则详解(二)
			接上篇 ESLint 规则详解(一) 前端界大神 Nicholas C. Zakas 在 2013 年开发的 ESLint,极大地方便了大家对 Javascript 代码进行代码规范检查.这个工具包含 ... 
- 代理神器allproxy
			背景 allproxy意为all as proxy,即是说所有设备均可以成为一个网络代理,唯一的要求就是有网络访问权限. 一般的代理软件要求宿主机必须有公网地址,然后才能把网络代理出去,但在实际情况下 ... 
