USACO 2.1.3 Sorting a Three-Valued Sequence解题报告

来源:互联网 发布:java validation 日期 编辑:程序博客网 时间:2024/05/14 06:31

原题链接:

一看这道题就想到了离散上学的置换群,按置换群做了做,果然AC了!

先讲一下思考过程:             

       index:    1   2   3   4   5   6   7   8   9                     

     原数据:    2   2   1   3   3   3   2   3   1                               

     排序后:    1   1   2   2   2   3   3   3   3                                   

    分组后  index:           1    3               2    9    5               4    7                     6       8      

                                       2    1               2    1    3               3    2                     3       3

                                       1    2               1    3    2               2    3                     3       3

                              从上面的分组可看出第一组和第三组交换一次,第二组和第五组交换一次,第五组再和第九组交换一次,第四组和第七组交换一次,这样一共交换了4次,

                      就是答案了!

                             关键是如何进行分组呢?这就用到了离散上的知识,将群转换为轮换和对换之积的形式,然后分别计算出对换或轮换中数的个数再减一就是交换的次数,把

                      所有次数累加就是总的交换次数了。但是要注意一种情况如果找的轮换是如下形式,则要进行处理在计算次数:

                         2     1      3      1     3                    ---------->                    2     1     3              3     1        

                         1     3      1      3     2                                                       1      3     2              1     3

                     这组数据有个特点就是轮换之中包含着对换,直接计算交换次数是4次,但是我们可以把它拆成右边的两组,交换次数变为2+1=3次。显然右边的交换次数少,

                     是我们需要的。当遇到这种数据时,方法是找出轮换中对换的个数,然后总的次数减去对换的个数。在此例中有一个对换,就是4-1=3了。

源代码:

/*ID: supersnow0622PROG: sort3LANG: C++*/#include <iostream>#include <fstream>#include <string>#include<algorithm>#include<memory.h>using namespace std;int arr[1001],byOrder[1001],used[1001],judge[4];int main() {    ofstream fout ("sort3.out");    ifstream fin ("sort3.in");    int N,start,count;    cin>>N;    for(int i=0;i<N;i++)    {     cin>>arr[i];     byOrder[i]=arr[i];    }    sort(byOrder,byOrder+N);    int index,temp,sum=0;    for(int i=0;i<N;i++)     if(arr[i]==byOrder[i])       used[i]=1;    for(int i=0;i<N;i++)    {      memset(judge,0,sizeof(judge));      if(!used[i]){      start=arr[i];      count=0;      judge[start]=1;      used[i]=1;      index=i;      while(byOrder[index]!=start)      {        sum++;        temp=byOrder[index];        int j;        for(j=0;j<N;j++)        {          if(arr[j]==temp&&!used[j])            {              judge[temp]=1;              used[j]=1;              break;            }        }        index=j;        if(judge[byOrder[index]]==1)          {            memset(judge,0,sizeof(judge));             judge[start]=1;            count++;          }      }       if(count!=1)           sum=sum-count+1;    }    }     cout<<sum;    return 0;}


       

原创粉丝点击