题目:
题目描述
有N(1≤N≤1000)头奶牛,它们都被标上一个优先等级编号:1,2或3。用来表示它们喝水时的优先次序,编号为l的最优先,编号为2的其次,编号为3的最后。每天奶牛开始时排成一行,但总是很乱,需要你把它们重新排成编号为1的奶牛在最前面,编号为2的其次,编号为3的奶牛在最后。你能计算出最少需要多少的交换次序来完成这次重排吗?
输入
第1行:1个整数N;
第2至N+I行:第i+l行有一个整数表示开始队列中第i头奶牛的编号。
输出
1行,只一个整数,表示最少需要交换次数。
样例输入
9
2 2 1 3 3 3 2 3 1
样例输出
4
思路:
在读入的时候记录一下1 2 3
三个数的数目,然后就可以确定排完序之后他们的界限,然后从1的区域开始扫,扫到2就优先去2的区域找,找不到就去3的区域找,扫到3同理,这样就能保证每一次交换都是最优的,将2区域扫完之后也就完成了所有的交换。
实现:
#include <bits/stdc++.h>
using namespace std;
#define maxn 1007
int a[maxn],b[maxn],cnt[7],wall[7][2],n,result;
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
ios_base::sync_with_stdio(false);cin.tie(0);
while(memset(cnt,0,sizeof cnt),cin >> n) {
for(int i=1 ; i<=n ; i++) cin >> a[i],b[i] = a[i],cnt[a[i]]++;
wall[1][0] = 1, wall[1][1] = cnt[1],wall[2][0] = cnt[1] + 1,
wall[2][1] = cnt[1] + cnt[2],wall[3][0] = wall[2][1] + 1, wall[3][1] = n;
sort(b+1,b+1+n);
for(int i=1 ; i<=n ; i++)
if(a[i] != b[i]) {
int l=wall[a[i]][0], r=wall[a[i]][1];
for(int j=l ; j<=r ; j++)
if(a[j] == b[i]) {
swap(a[i],a[j]);
result++;
break;
}
if(a[i] != b[i]) {
int tmp;
if(a[i] == 2) tmp = 3;
else tmp = 2;
l=wall[tmp][0], r=wall[tmp][1];
for(int j=l ; j<=r ; j++)
if(a[j] == b[i]) {
swap(a[i],a[j]);
result++;
break;
}
}
}
cout << result << '\n';
}
return 0;
}