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

    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步的情况:在第一轮中应当先争取一步到位,这样可以减少一次交换次数。
  本题还有个需要注意的地方(快排、二分等方法中也常出现这个问题),为了让下标不超出范围,要随时判断是否越界。

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

【代码】

 1 /*
 2 ID: icedrea1
 3 PROB: sort3
 4 LANG: C++
 5 */
 6
 7 #include <iostream>
 8 #include <fstream>
 9 using namespace std;
10
11 int N,d[1001];
12 int num[4];
13
14 int main()
15 {
16     ifstream in("sort3.in");
17     ofstream out("sort3.out");
18
19     in>>N;
20     for(int i=1;i<=N;++i) { in>>d[i]; ++num[d[i]]; }
21     num[2]+=num[1];
22
23     // The situation of vector d:
24     //  1: d[1]~d[num[1]]
25     //  2: d[num[1]+1]~d[num[2]]
26     //  3: d[num[2]+1]~d[N]
27
28     int s=0;
29     for(int i=1,j=num[1]+1,k=num[2]+1;;)
30     {
31         while(i<=num[1] && d[i]==1) ++i;
32         if(i==num[1]+1) break;
33         while(j<=num[2] && d[j]!=1) ++j;
34         while(k<=N && d[k]!=1) ++k;
35         ++s;
36         if(d[i]==2 && j<=num[2]) swap(d[i],d[j]); else if(d[i]==3 && k<=N) swap(d[i],d[k]); // 一步换到位更优
37         else if(j<=num[2]) swap(d[i],d[j]); else swap(d[i],d[k]); // 无法一步到位,那就换个合法的就行
38     }
39     for(int i=num[1]+1,j=num[2]+1;;)
40     {
41         while(i<=num[2] && d[i]==2) ++i;
42         if(i==num[2]+1) break;
43         while(j<=N && d[j]!=2) ++j;
44         swap(d[i],d[j]); ++s;
45     }
46
47     out<<s<<endl;
48
49     in.close();
50     out.close();
51     return 0;
52 }
时间: 2024-12-11 03:47:48

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

hdu 1711 Number Sequence 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 题目意思:给出一条有n个数的序列a[1],a[2],......,a[n],和一条有m 个数的序列b[1],b[2],......,b[m],求出b[1],b[2],...,b[m]在序列a中完全匹配时,在序列a中的位置,如果找不到输出-1. 这几天一直在学kmp,该题算是kmp的入门题吧.有个地方要稍稍注意,代码中,主串和模式串的比较初始值为-1,-1,否则如果从0开始,会默认第一个字符是相

Ducci Sequence解题报告

A Ducci sequence is a sequence of n-tuples of integers. Given an n-tuple of integers (a1, a2, ... , an), the next n-tuple in the sequence is formed by taking the absolute differences of neighboring integers: ( a1, a2, ... , an)  (| a1 - a2|,| a2 - a3

【LeetCode】Longest Consecutive Sequence 解题报告

[题目] Given an unsorted array of integers, find the length of the longest consecutive elements sequence. For example, Given [100, 4, 200, 1, 3, 2], The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4. Your algorithm should

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

Time Limit:1000MS     Memory Limit:32768KB Description ?A number sequence is defined as follows:f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.Given A, B, and n, you are to calculate the value of f(n). Input The input consists of mult

LeetCode: Permutation Sequence 解题报告

Permutation Sequence https://oj.leetcode.com/problems/permutation-sequence/ The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the permutations in order, We get the following sequence (ie, for n = 3): "123&

LeetCode: Longest Consecutive Sequence 解题报告

Longest Consecutive Sequence Given an unsorted array of integers, find the length of the longest consecutive elements sequence. For example,Given [100, 4, 200, 1, 3, 2],The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4.

Hdu 5064 Find Sequence 解题报告

题目出处:http://acm.hdu.edu.cn/showproblem.php?pid=5064 题意:给定n个数,求满足以下两个条件的子序列的最大长度: (1)C1<C2<C3<......<Ct; (2)C2-C1<C3-C2<......<Ct-Ct-1. 分析:解结构一定为为N1,N1,N1,......,N1,N2,N3,......,Nt   设dp[i][j]表示以num[i], num[j]结尾的有效序列的长度,则有         dp[i

UVa -1584 Circular Sequence 解题报告

1.题目大意 输入长度为n$(2\le n\le 100)$的环状DNA串,找出该DNA串字典序最小的最小表示. 2.思路 这题特别简单,一一对比不同位置开始的字符串的字典序,更新result. 3.代码 #include"stdio.h" #include"string.h" #define maxn 100 int judge(char* s,int p,int q) //比较p的字典序是否比q小 { int m=strlen(s); for(int i=0;

[Baltic2014]sequence 解题报告

想了很久还是不会..然后开始各种乱搞全都不行.. 最后看了题解感觉好厉害! 首先我们将问题放缩.设x的每一位的数字集合是S(x),则对于给定数列{Bi}(i∈[0,k)),Bi∈{0,1,2,3,4,5,6,7,8,9},?i∈[0,k),要求Bi∈S(n+i),求最小的n. 这样的话,如果我们枚举n的个位,就会将问题转化为10个k10规模的问题! 当k=1时,显然就可以直接贪心了. 所以时间复杂度就是O(10?klog10k)的. 但是还有不少非常蛋碎的细节.. 当k=2的时候,我们可能会选择