天天看點

USACO Section 2.1 Sorting A Three_Valued Sequence - 應該有更好的方法

    題目的意思是有一列數隻由1,2,3組成~~~需要咱們将1放在一起排在最前面~~~2放在一起排在中間~~~3放在一起放後面~~問對于這個數列最少要進行多少次交換...

    我的方法是先統計1,2,3的個數~~那麼就可以知道1,2,3分辨該放在哪個區域~~

    首先将1都放到該放的位置~~其所需步數就是找2~3的區域中1的個數~~然後再看1這個區域裡有多少個2可以直接和2區域的交換~~有多少個3可以直接和3區域的交換~~~做完後這是1已經放好了~~而且1中的2都盡量的往2區域放~~1中的3也在盡量的往3區域放~~那麼這是2,3區域裡面已經沒有1了~~~并且顯然的是2區域裡的3=3區域裡的2~~是以任意統計一個區域~~就找到2,3區域互相需要交換的次數了~~兩次之和既是答案~~

    冥冥之中感覺沒必要用這種可以說是純模拟的方法~~~想推一個更快捷的~~可一直錯誤~~

/*  
ID: zzyzzy12  
LANG: C++  
TASK: sort3
*/    
#include<iostream>    
#include<stdio.h>    
#include<string.h>    
#include<math.h>    
#include<algorithm>    
#include<queue>
using namespace std;    
int a[1002],g[4],i,ans,n,j; 
int main()
{
     freopen("sort3.in","r",stdin);
     freopen("sort3.out","w",stdout);   
     scanf("%d",&n);
     memset(g,0,sizeof(g)); 
     for (i=1;i<=n;i++)
     {
           scanf("%d",&a[i]);
           g[a[i]]++;
     } 
     for (i=1;i<=3;i++) g[i]+=g[i-1];
     ans=0; 
     for (i=1;i<=g[1];i++)
     if (a[i]!=1)
     {
           ans++;
           if (a[i]==2)
           {
                for (j=g[1]+1;j<=g[2];j++)    
                  if (a[j]==1) { a[j]=2;  goto A;}  
                for (j=g[2]+1;j<=n;j++)
                  if (a[j]==1) { a[j]=2;  goto A; }
           }else
           {
                for (j=g[2]+1;j<=n;j++)    
                  if (a[j]==1) { a[j]=3;  goto A;}  
                for (j=g[1]+1;j<=g[2];j++)
                  if (a[j]==1) { a[j]=3; goto A; }             
           }  
           A: ;
     }
     for (i=g[2]+1;i<=n;i++)
      if (a[i]==2) ans++;
     printf("%d\n",ans);     
     return 0;   
}