[1119] Patchouli's Books

来源:互联网 发布:mac如何下载土豆视频 编辑:程序博客网 时间:2024/06/09 21:14
  • 问题描述
  • Patchouli Knowledge(パチュリー·ノーレッジ) is the owner of the Embodiment of Scarlet Devil library. She often shelves books time by time.
    For she is careless, Patchouli treats all the books in the same size in the same way.
    Give you several books and their sizes (you only need to consider the height of the books), you should output all the books formations Patchouli may shelf.

  • 输入
  • This problem may contains several cases.
    The first line is a single integer N (0 < N <= 8), indicates the number of books.
    The next line has N integers, the ith integer Hi (0 < Hi <= 15) indecate the height of the ith book.
  • 输出
  • For each case, you have to output the all the possible formations (According to the height difference). Order by lexicographic order. The height will be outputed in hexadecimal.

    上离散课的时候,老师讲了关于排列组合的2个算法,一个是字典序法,一个是邻位交换法,今天试着把前者写了出来,并A了这题,至于后者,由于字典序输出的问题,暂时还没写
    介绍下字典序法
    字典序法中,对于数字1、2、3......n的排列,不同排列的先后关系是从左到右逐个比较对应的数字的先后来决定的。例如对于5个数字的排列12354和12345,排列12345在前,排列12354在后。按照这样的规定,5个数字的所有的排列中最前面的是12345,最后面的是54321。
      字典序算法如下:
      设P是1~n的一个全排列:p=p1p2......pn=p1p2......pj-1pjpj+1......pk-1pkpk+1......pn
      1)从排列的右端开始,找出第一个比右边数字小的数字的序号j(j从左端开始计算),即 j=max{i|pi<pi+1}
      2)在pj的右边的数字中,找出所有比pj大的数中最小的数字pk,即 k=min{i|pi>pj}(右边的数从右至左是递增的,因此k是所有大于pj的数字中序号最大者)
      3)对换pi,pk
      4)再将pj+1......pk-1pkpk+1......pn倒转得到排列p’=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1,这就是排列p的下一个下一个排列。
      例如839647521是数字1~9的一个排列。从它生成下一个排列的步骤如下:
      自右至左找出排列中第一个比右边数字小的数字4 839647521
      在该数字后的数字中找出比4大的数中最小的一个5 839647521
      将5与4交换 839657421
      将7421倒转 839651247
      所以839647521的下一个排列是839651247。
    //字典序法 #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;char hex[6]={'A','B','C','D','E','F'};int main(){int str[20];int len;while(~scanf("%d",&len)){int i,j,k,a,b,Max_min;for(i=0;i<len;i++){scanf("%d",&str[i]);  }sort(str,str+len);while(1) {Max_min=0x3f3f3f;for(i=0;i<len-1;i++)    if(str[i]<=9)       printf("%d ",str[i]);                else                   printf("%c ",hex[str[i]-10]);            if(str[len-1]<=9)            printf("%d\n",str[len-1]);            else                printf("%c\n",hex[str[len-1]-10]);for(i=len-1;i>=1;i--)    if(str[i]>str[i-1]) //从右往左找第一对正序数    {    a=str[i-1];    k=i-1;    break;    }  if(i<=0)                  break;            for(i=len-1;i>k;i--)    if(str[i]>a && str[i]<Max_min){j=i;Max_min=str[i];//从右向左找出一个最小的数,它比a要大 ,最靠右 }    //交换    str[k]=str[k]^str[j];str[j]=str[j]^str[k];str[k]=str[k]^str[j];for(i=k+1,j=len-1;i<j;i++,j--){str[i]=str[i]^str[j];    str[j]=str[j]^str[i];    str[i]=str[i]^str[j];}}  }return 0;}


0 0
原创粉丝点击