题目描述
有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 }
View Code
如有错误,请指正,感谢!