USACO sort3

来源:互联网 发布:黄金价格数据 编辑:程序博客网 时间:2024/06/05 02:25

题意:给你一个只有1、2、3的数列,要你求出任意交换两个之后成为升序的最少次数。
题解:一开始本来也想到了拿初始状态与结束状态做对比,发现有些不好搞便去想构造算法去了,自然是没有想得出。题解把开始和结束的对应数字连一条边,这样会形成很多环,答案就是环的长度之和减去环的个数了。
还有一种搞法,把那些只要交换一次就两个都到位的对交换,ans++,这些对肯定是必要的。剩下的就是那些交换一次都不能到位的对,这些对肯定是三个三个一组的,每一组都需要两次来交换。比如:
初始 3 3 1 1 2 2
结束 1 1 2 2 3 3
可以发现交换任意两个都不能到位,所以就要交换两次了。答案就加上结束为1但当前不为1的个数乘2。

/*ID: d2947901PROG: sort3LANG: C++*/#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#include<iostream>#define X first#define Y second#define MP make_pair#define LL long long#define pb push_back#define DEBUG(...) fprintf(stderr,__VA_ARGS__)using namespace std;const int MAXN=1001;int n,a[MAXN],ans=0,b[MAXN];int main(){    freopen("sort3.in","r",stdin);    freopen("sort3.out","w",stdout);    cin>>n;    for(int i=1;i<=n;i++)        cin>>a[i];    memcpy(b,a,sizeof(a));    sort(b+1,b+n+1);    for(int i=1;i<=n;i++)    {        if(a[i]==b[i])continue;        for(int j=i+1;j<=n;j++)        {            if(a[i]==b[j]&&a[j]==b[i])            {                ans++;                swap(a[i],a[j]);                break;            }        }    }    for(int i=1;i<=n;i++)        if(b[i]==1&&a[i]!=1)            ans+=2;    printf("%d\n",ans);}
0 0