USACO-Section2.1 Sorting a Three-Valued Sequence [其他][排序][交换]
2017-07-16 15:22
423 查看
题目大意
排序是一种很频繁的计算任务。现在考虑最多只有三值的排序问题。一个实际的例子是,当我们给某项竞赛的优胜者按金银铜牌排序的时候。在这个任务中可能的值只有三种1,2和3。我们用交换的方法把他排成升序的。写一个程序计算出,给定的一个1,2,3组成的数字序列,排成升序所需的最少交换次数。
题解
NOCOW上给出过一种思路:题意求排序所需的最少移动次数,可以先将输入的数字排序,然后得到不同的地方
比如:
2 2 1 3 3 3 2 3 1
1 1 2 2 2 3 3 3 3
用一个组合(a,b)表示应该排序后某个位置应该是a,但之前的是b
则我们得到(1,2), (1,2), (2,1), (2,3), (2,3), (3,2), (3,1)
然后求这些组合能组成的环,结果就是所有环的长度和减去环的个数
(1,2), (2,1) —长度为2
(1,2), (2,3), (3,1) —长度为3
(2,3), (3,2) —长度为2
结果2+3+2-3=4
这个思路是没错的,但有一点需要注意,算法必须保证先消去小环,再消去大环。比如上例中完全可以出现(1,2),(2,3),(3,2),(2,3),(3,1)这样的环。多个小环的代价要小于一个大环。
上例中 (1,2),(2,3),(3,2),(2,3),(3,1) 是由 (1,2),(2,3)(3,1) 和(3,2), (2,3)组合成的。也就是说,一个5元的环,有可能是一个二元环和一个三元环组成的。一个真五元环需要交换4次,真3元环需要交换2次,一个2元环只需要交换1次,所以把它看成一个大环和多个小环是不一样的。而且多个小环的代价要小于一个大环。
长度为n的环,交换次数/元素个数=(n−1)/n所以n越小,其比值越小。所以我们需要先把小环中的数字交换,再处理更大的环。
那么怎么才能保证先消去小环,在消大环呢?
对于这一题,只有三种元素,1、2、3,所以所有可能的环的情况只有4种:
1. (1,2), (2,1)
2. (2,3), (3,2)
3. (1,3), (3,1)
4. (1,2), (2,3), (3,1) 或 (1,3), (3,2), (2,1)
我们只需要先把所有的二元环都处理完再处理三元的环就可以了。
把整个数组分成3部分,这3部分分别是排好序后1,2,3的位置。
令c[i][j] = 在第i个位置上的数字j的个数。例如
原数组:2 2 | 1 3 3 | 3 2 3 1
排序后:1 1 | 2 2 2 | 3 3 3 3
可以看出 c[1][1] = 0, c[1][2] = 2,c[1][3] = 0,…
然后就可以按照上面的方法从小到大寻找环了。
代码
/* ID: zachery1 PROG: sort3 LANG: C++ */ #include<iostream> #include<fstream> #include<cstring> #define N 1001 #define cout fout #define cin fin using namespace std; ifstream fin("sort3.in"); ofstream fout("sort3.out"); int main() { int n; int ans=0; int a ={0}; int b[4]={0}; int c[4][4]={0}; cin >> n; for(int i=0; i<n; i++) { cin >> a[i]; b[a[i]]++; } int k1, k2; k1 = b[1]; k2 = b[1]+b[2]; for(int i=0; i<k1; i++) c[1][a[i]]++; for(int i=k1; i<k2; i++) c[2][a[i]]++; for(int i=k2; i<n; i++) c[3][a[i]]++; while(c[1][2] && c[2][1]) { c[1][2]--; c[2][1]--; ans++; } while(c[1][3] && c[3][1]) { c[1][3]--; c[3][1]--; ans++; } while(c[2][3] && c[3][2]) { c[2][3]--; c[3][2]--; ans++; } while(c[1][2] && c[2][3] && c[3][1]) { c[1][2]--; c[2][3]--; c[3][1]--; ans+=2; } while(c[1][3] && c[3][2] && c[2][1]) { c[1][3]--; c[3][2]--; c[2][1]--; ans+=2; } cout << ans << endl; return 0; }
相关文章推荐
- USACO-Section2.1 Sorting a Three-Valued Sequence(排序)
- USACO-Section2.1 Sorting a Three-Valued Sequence[排序]
- USACO - Chapter2 Section 2.1 - Sorting a Three-Valued Sequence
- USACO Section2.1 Sorting a Three-Valued Sequence 解题报告
- USACO-Section2.1 Sorting a Three-Valued Sequence【数学公式】
- USACO Section 2.1: Prob Sorting A Three-Valued Sequence
- [USACO2.1]三值的排序 Sorting a Three-Valued Sequence
- USACO-Section 2.1 Sorting a Three-Valued Sequence (贪心)
- USACO2.1 三值的排序 Sorting a Three-Valued Sequence
- USACO 2.1.3 Sorting a Three-Valued Sequence 三值的排序
- [2016/7/11][usaco 2.1]Sorting a Three-Valued Sequence
- USACO 2.1 Sorting a Three-Valued Sequence (乱搞)
- USACO [2.1] Sorting a Three-Valued Sequence
- 【USACO 2.1】Sorting A Three-Valued Sequence
- USACO-Section2.1 Ordered Fractions [其他][排序]
- USACO 2.1 Sorting a Three-Valued Sequence
- USACO 2.1-Sorting a Three-Valued Sequence
- USACO 2.1 Sorting a Three-Valued Sequence
- USACO 2.1 Sorting A Three-Valued Sequence
- USACO 2.1 Sorting A Three-Valued Sequence