USACO 2.1 Sorting A Three-Valued Sequence


两个数,如果它们现在的位置和最终排序后的位置恰好相反,那么将这两个数互换,就不需要再动了。对于这样的数,互换次数为1。
除此之外,可能是1在2的位置上,2在3的位置上,3在1的位置上或1在3的位置上,3在2的位置上,2在1的位置上。这样形成一个环。这个环换2次,即可排好序。

首先用计数排序计算好某一个数应该在的位置,然后分别计算出上面两种情形的数目。相加即可。

#include <iostream>
#include 
<fstream>

using namespace std;

ifstream fin(
"sort3.in");
ofstream fout(
"sort3.out");

#ifdef _DEBUG
#define out cout
#define in cin
#else
#define out fout
#define in fin
#endif

// sum[i]:i的最终位置为sum[i-1]->sum[i]之间
int sum[4];
// cnt[i][j] i位置上j的数目
int cnt[4][4]; 
//存储原始输入数据
int data[1000];

//排好序后,第i个位置应该是什么数
int get_num(int i)
{
    
if(i<=sum[1]) return 1;
    
else if(i<=sum[2]) return 2;
    
else return 3;
}

void solve()
{
    
int n;
    
in>>n;
   
    
int tmp;

    
for(int i=0;i<n;++i){
        
in>>data[i];
        sum[ data[i] ] 
++;
    }

    sum[
2]+=sum[1];
    sum[
3]+=sum[2];

    
for(int i=0;i<n;++i){
        cnt[get_num(i
+1)][data[i]]++;
    }

    
int res = 0;

    
for(int i=1;i<=3;++i){
        
for(int j=1;j<=3;++j){
            
if(i==j) continue;
           tmp 
= min(cnt[i][j],cnt[j][i]);
           cnt[i][j]
-=tmp;
           cnt[j][i]
-=tmp;
           res
+=tmp;
        }
    }

    res
+=min(cnt[2][3],min(cnt[3][1],cnt[1][2]))*2;
    res
+=min(cnt[2][1],min(cnt[3][2],cnt[1][3]))*2;

    
out<<res<<endl;
}

int main(int argc,char *argv[])
{
    solve(); 
    
return 0;
}


posted on 2009-06-19 20:07 YZY 阅读(1134) 评论(0)  编辑 收藏 引用 所属分类: AlgorithmUSACO


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2009年6月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

统计

常用链接

留言簿(2)

随笔分类

随笔档案

搜索

积分与排名

最新评论

阅读排行榜