题目描述
有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
提示
样例说明:有一种交换方法。
2 2 2< 1 1
2< 1 1 1 1
1< 2 2 2 2
3 3< 2 2 2
3 3 3 3< 2
3 3 3 3 3
2 2< 3 3 3
3 3 3 3 3
1 1 1< 2< 3
我们可以定义一个cnt[]来记录1,2,3的个数,然后分块来讨论。首先在1的区域(即1~cnt[1])遍历,如果a[i]==2,那么就去2的区域找1并替换,如果2的区域没有1,就去3的区域;如果a[i]==3,那么就去3的区域找1并替换,如果3的区域没有1,就去2的区域。接着就在2的区域(即cnt[1]+1~cnt[1]+cnt[2]),因为我们此时已经确保了1的区域只有1,那么2只能出现在2和3的区域,所以我们只需要看此时2的区域中有多少个3就行了。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 int n,a[1005],cnt[5]; 5 int main() 6 { 7 cin>>n; 8 for(int i=1;i<=n;i++) 9 { 10 cin>>a[i]; 11 cnt[a[i]]++; 12 } 13 int ans=0; 14 for(int i=1;i<=cnt[1];i++) 15 { 16 if(a[i]==2) 17 { 18 for(int j=cnt[1]+1;j<=cnt[2]+cnt[1];j++) 19 { 20 if(a[j]==1) 21 { 22 ans++; 23 swap(a[i],a[j]); 24 break; 25 } 26 } 27 if(a[i]==2) 28 { 29 for(int j=cnt[1]+cnt[2]+1;j<=n;j++) 30 { 31 if(a[j]==1) 32 { 33 ans++; 34 swap(a[i],a[j]); 35 break; 36 } 37 } 38 } 39 } 40 else if(a[i]==3) 41 { 42 for(int j=cnt[1]+cnt[2]+1;j<=n;j++) 43 { 44 if(a[j]==1) 45 { 46 ans++; 47 swap(a[i],a[j]); 48 break; 49 } 50 } 51 if(a[i]==3) 52 { 53 for(int j=cnt[1]+1;j<=cnt[2]+cnt[1];j++) 54 { 55 if(a[j]==1) 56 { 57 ans++; 58 swap(a[i],a[j]); 59 break; 60 } 61 } 62 } 63 } 64 } 65 for(int i=cnt[1]+1;i<=cnt[1]+cnt[2];i++) 66 { 67 if(a[i]!=2) 68 ans++; 69 } 70 cout<<ans<<endl; 71 }