1,2,3的交换

 

排序是一种很频繁的计算任务。现在考虑最多只有三值的排序问题。一个实际的例子是,当我们给某项竞赛的优胜者按金银铜牌序的时候。 在这个任务中可能的值只有三种1,2和3。我们用交换的方法把他排成升序的。 写一个程序计算出,给定的一个1,2,3组成的数字序列,排成升序所需的最少交换次数。

Input

Line 1: N (1 <= N <= 1000) Lines 2-N+1: 每行一个数字,共N行。(1..3)

Output

共一行,一个数字。表示排成升序所需的最少交换次数。

Sample Input

9
2
2
1
3
3
3
2
3
1

Sample Output

4

一直是答案错误,终于找到原因了,第一区间要分情况,当第一区间是2时,优先跟第二区间换,要是第二区间没有可换的,去第三区间换;当第一区间是3时,跟第三区间换。然后看第二三区间只剩2和3了,这时候就跟第三区间换,而且是倒着换^^具体看代码吧~

#include <stdio.h>
int main()
{
    int i,a[10000]={0},n,x=0,y=0,z=0,sum=0,t,j;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        if(a[i]==1)
            x++;
        if(a[i]==2)
            y++;
        if(a[i]==3)
            z++;
    }
    int m=0;
    for(i=0;i<x;i++)
    {
        for(j=0;j<x;j++)
            if(a[j]!=1)
              break;
        if(j>=x)
        {
            m=1;
            break;
        }
        int b=0;
        if(a[i]==2)
        {
            for(j=x;j<x+y;j++)//优先跟第二区间换
            {
                if(a[j]==1)
                {b++;t=a[j];a[j]=a[i];a[i]=t;
                sum++;break;}
            }
        }
        if(a[i]==2&&m==0&&b==0)//当第二区间有1而且第一区间不全是1,就去第三区间找
        {
            for(j=x+y;j<n;j++)
                if(a[j]==1)
                 {t=a[j];a[j]=a[i];a[i]=t;
                sum++;break;}
        }
        if(a[i]==3)
        {
            for(j=n-1;j>=x;j--)
                if(a[j]==1)
                {t=a[j];a[j]=a[i];a[i]=t;
             sum++;break;}
        }
    }
    for(i=x;i<x+y;i++)
    {
        for(j=x;j<x+y;j++)
            if(a[j]!=2)
               break;
        if(j>=x+y)
            break;
        for(j=n-1;j>=x+y;j--)
             if(a[j]==2&&a[i]!=2)
           {t=a[i];a[i]=a[j];a[j]=t;sum++;break;}
    }
    printf("%d\n",sum);
    return 0;
}

   另一个思路:整体是先换两个都满足的  再换必须换的

第一步:在A区间里 如果是2的话 就去B区间里换  是3的话就去C区间换

                在B区间里 如果是3的话 就去C区间里换

第二步:如果A区间里有不是1的 就去剩余区间里换

                如果B区间里不是2的 就去C区间里换

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <deque>
using namespace std;
typedef long long ll;
int main()
{
    ll i,j,a=0,b=0,c=0,ans=0,t;
    ll n,s[1010];
    cin>>n;
    for(i=0; i<n; i++)
    {
        cin>>s[i];
        if(s[i]==1)
            a++;
        else if(s[i]==2)
            b++;
        else if(s[i]==3)
            c++;
    }
    for(i=0; i<a; i++)
    {
        if(s[i]==2)
        {
            for(j=a; j<a+b; j++)
            {
                if(s[j]==1)
                {
                    t=s[j];
                    s[j]=s[i];
                    s[i]=t;
                    ans++;
                    break;
                }
            }
        }
        if(s[i]==3)
        {
            for(j=a+b; j<n; j++)
            {
                if(s[j]==1)
                {
                    t=s[i];
                    s[i]=s[j];
                    s[j]=t;
                    ans++;
                    break;
                }
            }
        }
    }
    for(i=a; i<a+b; i++)
    {
        if(s[i]==3)
        {
            for(j=a+b; j<n; j++)
            {
                if(s[j]==2)
                {
                    t=s[i];
                    s[i]=s[j];
                    s[j]=t;
                    ans++;
                    break;
                }
            }
        }
    }
    for(i=0; i<a; i++)
    {
        if(s[i]!=1)
        {
            for(j=a; j<n; j++)
            {
                if(s[j]==1)
                {
                    t=s[i];
                    s[i]=s[j];
                    s[j]=t;
                    ans++;
                    break;
                }
            }
        }
    }
    for(i=a; i<a+b; i++)
    {
        if(s[i]!=2)
        {
            for(j=a+b; j<n; j++)
            {
                if(s[j]==2)
                {
                    t=s[j];
                    s[j]=s[i];
                    s[i]=t;
                    ans++;
                    break;
                }
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}


   

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值