USACO Sorting a Three-Valued Sequence

首先来看一下题目:

Sorting is one of the most frequently performed computational tasks. Consider the special sorting problem in which the records to be sorted have at most three different key values. This happens for instance when we sort medalists of a competition according to medal value, that is, gold medalists come first, followed by silver, and bronze medalists come last.

In this task the possible key values are the integers 1, 2 and 3. The required sorting order is non-decreasing. However, sorting has to be accomplished by a sequence of exchange operations. An exchange operation, defined by two position numbers p and q, exchanges the elements in positions p and q.

You are given a sequence of key values. Write a program that computes the minimal number of exchange operations that are necessary to make the sequence sorted.

PROGRAM NAME: sort3

INPUT FORMAT

Line 1: N (1 <= N <= 1000), the number of records to be sorted
Lines 2-N+1: A single integer from the set {1, 2, 3}

SAMPLE INPUT (file sort3.in)

9
2
2
1
3
3
3
2
3
1

OUTPUT FORMAT

A single line containing the number of exchanges required

SAMPLE OUTPUT (file sort3.out)

4

这道题的思路是这样的,首先,如果可以两两交换的,就两两交换,否则就三个轮换。

在没有任何改变的情况下,值是这样的:

此时所说的两两交换首先是第0组与第2组的交换,此时可以看到第0组和第2组的当前值发生了交换

同理,第3组与第6组交换

此时第1组、第4组、第8组的都不满足两两交换的条件,因此第1组与第4组交换,此时第4组得到了满足

最后将第1组与第8组交换

从上面的步骤可以看出来,如果出现了无法两两交换的元素,那么每三组需要交换两次。至于为什么这样做交换次数最少,我目前是靠的直觉。

/**
ID: njuwz151
TASK: sort3
LANG: C++
**/
#include <bits/stdc++.h>

using namespace std;

const int maxn = 1005;
int n;
int number[maxn];
int expected[maxn];
int m_count[] = {0, 0, 0};
int swap_time = 0;
void search();

int main() {
    freopen("sort3.in", "r", stdin);
    freopen("sort3.out", "w", stdout);

    cin >> n;
    for(int i = 0; i < n; i++) {
        cin >> number[i];
        m_count[number[i]-1]++;
    }
    for(int i = 0; i < m_count[0]; i++) {
        expected[i] = 1;
    }
    for(int i = m_count[0]; i < m_count[0] + m_count[1]; i++) {
        expected[i] = 2;
    }
    for(int i = m_count[0] + m_count[1]; i < n; i++) {
        expected[i] = 3;
    }
    search();
    cout << swap_time << endl;
} 

void search() {
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            if(i == j) {
                continue;
            }
            if(expected[i] == number[j] && expected[j] == number[i] && number[i] != number[j]) {
                swap(number[i], number[j]);
                swap_time++;
            }
        }
    }
    int unpair = 0;
    for(int i = 0; i < n; i++) {
        if(expected[i]!=number[i]) {
            unpair++;
        }
    }
    swap_time += unpair / 3 * 2;
}

void swap(int& a, int& b) {
    int temp = a;
    a = b;
    b = temp;
}
时间: 2024-12-24 17:42:47

USACO Sorting a Three-Valued Sequence的相关文章

Test Precisely and Concretely

Test Precisely and Concretely Kevlin Henney IT IS IMPORTANT TO TEST for the desired, essential behavior of a unit of code, rather than for the incidental behavior of its particular implementation. But this should not be taken or mistaken as an excuse

SIT120

Document Version: 2018-06-26 1 / 44SIT120> /unitchair "Henry Larkin"> /topic "Introduction to Responsive Web Apps"> /build web appsSIT120Document Version: 2018-06-26 2 / 44SIT120Table of ContentsOverview.......................

USACO Section 2.1 Sorting a Three-Valued Sequence

/* ID: lucien23 PROG: sort3 LANG: C++ */ #include <iostream> #include <fstream> #include <vector> #include <algorithm> using namespace std; void exchange(int nums[], int begin, int end, int N, int x); int sum = 0; int main() { ifst

USACO Train 2.1.3 Sorting a Three-Valued Sequence(sort3)

这道题就是给出由123三个值的一个数字序列,然后让你把这个序列升序排序,求最小的交换次数.注意这里可以不是相邻交换. 刚开始一看题的时候,还以为t=a a=b b=t那种水题呢,然后发现不是水题.. 于是就想思路...既然是排序题,就先把他排序好了,然后就再对比一下. 比如说USACO上的样例数据: 排序前   排序后 (1)2 1(2)2 1(3)1 2(4)3 2(5)3 2(6)3 3(7)2 3(8)3 3(9)1 3 既然他要求的是最少次数,那么我们就不要移动已经在原位不用移动的数据,

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

sort3解题报告 —— icedream61 博客园(转载请注明出处)------------------------------------------------------------------------------------------------------------------------------------------------[题目] 给你N,而后给出N个数,每个数都是1~3中的一个.请问,要把这个数列升序排好,最少需要进行几次两两交换?[数据范围] 1<=N<

USACO 2.1.3 Sorting a Three-Valued Sequence

题目大意: 这道题是说,给你一个长度为n的数组,然后,这个数组中只能包含1 2 3.求出将这个序列从小到大排序后的序列,所需要的最少的步数. 解题思路: 这道题,拿到后,想到以前做过的一个bit求逆序数的题目,想了想,完全不搭边啊.于是,发现了,由于这个数组中只有1 2 3 这三个数字,所以,我们首先应该先对原数组进行一份copy.然后对copy后的数组从小到大进行排序. 与现在的数组的每一位进行比较,记录相同位置不同地方的所有可能情况.发现,在交换的时候,要么是两个两个进行交换,1<->2

【USACO】Sorting a Three-Valued Sequence(思路)

拼了老命用一种贪心的思想把它A了,但是代码写的太烂了,而且时间复杂度为 n ^ 2,我就不多说了,太烂了 之后上网找了一个规律,时间复杂度为 nlogn,而且思路很明确,又写了一遍 代码:(贪心) /* ID: 18906421 LANG: C++ PROG: sort3 */ #include<cstdio> #include<cstring> #include<vector> #include<algorithm> using namespace std

[USACO][DAG上的动态规划]Sorting A Three-Valued Sequence

好美的图论,真的 light up my life!题意: 给出一个只含有若干1,2,3的数列,我们可以两两交换数列元素:要求输出让这个数列不减的最小交换次数. 思路: 首先看起来很像冒泡.....然鹅要最少交换次数——显然不是模拟冒泡了. 开始用深搜来着,显然没办法剪枝,果断T掉.这个时候就要想一想图论了. 想起来leetcode周赛的1247这道题.题目说的是有两个在{x,y}上相同长度的字符串,我们可以在两个字符串之间任选字符交换.求第一个字符串变成第二个字符串所需要的最小交换次数,有一点

2.1.3 Sorting a Three-Valued Sequence 三值的排序

2.1.3 Sorting a Three-Valued Sequence 三值的排序 一.题目描述 排序是一种很频繁的计算任务.现在考虑最多只有三值的排序问题.一个实际的例子是,当我们给某项竞赛的优胜者按金银铜牌序的时候. 在这个任务中可能的值只有三种1,2 和3.我们用交换的方法把他排成升序的. 写一个程序计算出,给定的一个1,2,3 组成的数字序列,排成升序所需的最少交换次数. PROGRAM NAME: sort3 INPUT FORMAT Line 1: N (1 <= N <= 1