sort3解题报告 —— icedream61 博客园(转载请注明出处)
------------------------------------------------------------------------------------------------------------------------------------------------
【题目】
  给你N,而后给出N个数,每个数都是1~3中的一个。请问,要把这个数列升序排好,最少需要进行几次两两交换?
【数据范围】
  1<=N<=1000
【输入样例】
  9
  2
  2
  1
  3
  3
  3
  2
  3
  1
【输出样例】
  4
------------------------------------------------------------------------------------------------------------------------------------------------
【分析】
  模拟一遍最优策略,便可得出答案,具体做法如下:
    1、读入N,并读入N个数d[1]~d[N],定义最少所需交换次数s=0
    2、统计下1~3分别的个数,得到1的个数num[1]和1、2的总个数num[2]。此时,便可确定最终1~3的位置分别是:
      1: 1~num[1]
      2: num[1]+1~num[2]
      3: num[2]+1~N
    3、第一轮交换,使所有的1都到位:
      i=1~num[1],找!=1的位置,不存在则不妨令i==num[1]+1
      当i==num[1]+1则说明所有1均到位,本轮结束。否则,
      j=num[1]+1~num[2],找==1的位置,不存在则不妨令j==num[2]+1
      k=num[2]+1~N,找==1的位置,不存在则不妨令j==N+1
      能到这里说明需要交换一次,故而++S,
      对当前i,首先争取一步换到位(即d[i]==2与d[j]换,或者d[i]==3与d[k]换),如不可能则找一个合法的换便可,不可能出现没有合法的换的情况。
    4、第二轮交换,使所有的2都到位(3自然也就都到位了):
      i=num[1]+1~num[2],找!=2的位置,不存在则不妨令i==num[2]+1
      当i==num[2]+1则说明所有2均到位,本轮结束。否则,
      j=num[2]+1~N,找==2的位置,不存在则不妨令j==N+1
      能到这里说明需要交换一次,故而++S,
      交换d[i]与d[j]。
    5、至此,两轮交换完成,所得s即为最少所需交换次数。
------------------------------------------------------------------------------------------------------------------------------------------------
【总结】
  开始没有注意到随便交换并非最优,没考虑到的就是分析中第3步的情况:在第一轮中应当先争取一步到位,这样可以减少一次交换次数。
  本题还有个需要注意的地方(快排、二分等方法中也常出现这个问题),为了让下标不超出范围,要随时判断是否越界。

------------------------------------------------------------------------------------------------------------------------------------------------

【代码】

 /*
ID: icedrea1
PROB: sort3
LANG: C++
*/ #include <iostream>
#include <fstream>
using namespace std; int N,d[];
int num[]; int main()
{
ifstream in("sort3.in");
ofstream out("sort3.out"); in>>N;
for(int i=;i<=N;++i) { in>>d[i]; ++num[d[i]]; }
num[]+=num[]; // The situation of vector d:
// 1: d[1]~d[num[1]]
// 2: d[num[1]+1]~d[num[2]]
// 3: d[num[2]+1]~d[N] int s=;
for(int i=,j=num[]+,k=num[]+;;)
{
while(i<=num[] && d[i]==) ++i;
if(i==num[]+) break;
while(j<=num[] && d[j]!=) ++j;
while(k<=N && d[k]!=) ++k;
++s;
if(d[i]== && j<=num[]) swap(d[i],d[j]); else if(d[i]== && k<=N) swap(d[i],d[k]); // 一步换到位更优
else if(j<=num[]) swap(d[i],d[j]); else swap(d[i],d[k]); // 无法一步到位,那就换个合法的就行
}
for(int i=num[]+,j=num[]+;;)
{
while(i<=num[] && d[i]==) ++i;
if(i==num[]+) break;
while(j<=N && d[j]!=) ++j;
swap(d[i],d[j]); ++s;
} out<<s<<endl; in.close();
out.close();
return ;
}

USACO Section2.1 Sorting a Three-Valued Sequence 解题报告的更多相关文章

  1. USACO Section 2.1 Sorting a Three-Valued Sequence 解题报告

    题目 题目描述 给N个整数,每个整数只能是1,2,或3.现在需要对这个整数序列进行从小到大排序,问最少需要进行几次交换.N(1 <= N <= 1000) 样例输入 9 2 2 1 3 3 ...

  2. timus 1175. Strange Sequence 解题报告

    1.题目描述: 1175. Strange Sequence Time limit: 1.0 secondMemory limit: 2 MB You have been asked to disco ...

  3. USACO Section 1.1 Your Ride Is Here 解题报告

    题目 问题描述 将字符串转变为数字,字母A对应的值为1,依次对应,字母Z对应的值为26.现在有一个字符串,将其中的每个字符转变为数字之后进行累乘,最终的结果对47求余数. 题目给你两个字符串,其中的字 ...

  4. LeetCode: Permutation Sequence 解题报告

    Permutation Sequence https://oj.leetcode.com/problems/permutation-sequence/ The set [1,2,3,…,n] cont ...

  5. LeetCode: Longest Consecutive Sequence 解题报告

    Longest Consecutive Sequence Given an unsorted array of integers, find the length of the longest con ...

  6. BZOJ 1367 [Baltic2004]sequence 解题报告

    BZOJ 1367 [Baltic2004]sequence Description 给定一个序列\(t_1,t_2,\dots,t_N\),求一个递增序列\(z_1<z_2<\dots& ...

  7. Winter-1-F Number Sequence 解题报告及测试数据

    Time Limit:1000MS     Memory Limit:32768KB Description ​A number sequence is defined as follows:f(1) ...

  8. 洛谷 P4597 序列sequence 解题报告

    P4597 序列sequence 题目背景 原题\(\tt{cf13c}\)数据加强版 题目描述 给定一个序列,每次操作可以把某个数\(+1\)或\(-1\).要求把序列变成非降数列.而且要求修改后的 ...

  9. gzhu 2013 Good Sequence 解题报告

    题目链接:(这个是内网的网址)  http://172.22.27.1/problem?pid=1013 Good Sequence Time Limit: 4000/2000 MS (Java/Ot ...

随机推荐

  1. Selenium入门17 selenium IDE安装及使用

    selenium IDE是firefox浏览器的一个插件,支持脚本的录制回放,关键字驱动的.界面跟robotframework很像. 实际测试中不用录制回放,不过初学者拿来看看元素是如何定位的还是有用 ...

  2. Javascript作业—数字转化为大写

    开始学javascript,写作业. <script type="text/javascript"> function toChinese(money){ var ch ...

  3. QT学习之QString的arg方法

    在QT的QString中,arg方法类似于C中的printf中使用的格式输出符(只是有点类似). 在QT5的帮助文档中,可以看出以下几点: 使用arg(str1, str2, str3)这种方法进行替 ...

  4. 写给future的话

    学习任何事务,永远不要被繁复的表象所迷惑. 觉得自己知识不够深,了解的不够多,其实就是思考感悟的不够罢了. 想,都是问题,做,才有答案 换位思考是人际交往最重要的能力之一.

  5. Hash模板

    ;//一般为靠近总数的素数 struct Hashtable { int x;//hash存的值 Hashtable * next; Hashtable() { next = ; } }; Hasht ...

  6. 创建 XXXXXXXX 的配置节处理程序时出错: 请求失败

    今天碰到这个错误,之前的程序在测试的时候都没有问题,同样的程序打包通过QQ传给其他人,在XP下测试也没有问题,我的Win7系统从QQ信箱下载压缩包,解压之后执行程序就会出问题,本来还是考虑自己程序是不 ...

  7. centos开启rewrite功能

    首先找到 /etc/httpd/conf/httpd.conf 文件,然后修改以下两个地方: 1.取消下面一句的注释 LoadModule rewrite_module modules/mod_rew ...

  8. 【JS-Java-EL】JavaScript和Java(EL表达式)引发的 Uncaught SyntaxError: Unexpected token ILLEGAL

    2018.10.14 BUG原因: 在较早期的代码中,容易出现 JS 拼接 HTML 代码字符串的情况.如 // 页面 test.jsp 内部的 JS 代码 // ${} JSP中EL语法,内部为Ja ...

  9. jquery操作DOM 元素(3)

    .detach() 从DOM 中去掉所匹配的元素. .detach([selector]) selector 一个选择表达式将需要移除的从匹配的元素中过滤出来. $("p").de ...

  10. 常见的HTTP状态码有哪些?

    当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求.当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求. ...