日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言实现数字全排列

發布時間:2023/12/20 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言实现数字全排列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一、問題描述
  • 二、代碼
  • 三、算法

一、問題描述

【問題描述】輸入整數N( 1 <= N <= 10 ),生成從1~N所有整數的全排列。

【輸入形式】輸入整數N。

【輸出形式】輸出有N!行,每行都是從1~N所有整數的一個全排列,各整數之間以空格分隔。各行上的全排列不重復。輸出各行遵循“小數優先”原則, 在各全排列中,較小的數盡量靠前輸出。如果將每行上的輸出看成一個數字,則所有輸出構成升序數列。具體格式見輸出樣例。

【樣例輸入1】1

【樣例輸出1】1

【樣例說明1】輸入整數N=1,其全排列只有一種。

【樣例輸入2】3?

【樣例輸出2】

1 2 3

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

【樣例說明2】輸入整數N=3,要求整數1、2、3的所有全排列, 共有N!=6行。且先輸出1開頭的所有排列數,再輸出2開頭的所有排列數,最后輸出3開頭的所有排列數。在以1開頭的所有全排列中同樣遵循此原則。

【樣例輸入3】10

【樣例輸出3】

1 2 3 4 5 6 7 8 9 10

1 2 3 4 5 6 7 8 10 9

1 2 3 4 5 6 7 9 8 10

1 2 3 4 5 6 7 9 10 8

1 2 3 4 5 6 7 10 8 9

1 2 3 4 5 6 7 10 9 8

1 2 3 4 5 6 8 7 9 10

1 2 3 4 5 6 8 7 10 9

1 2 3 4 5 6 8 9 7 10

1 2 3 4 5 6 8 9 10 7

……………………

【樣例說明3】輸入整數N=10,要求整數1、2、3、……、10的所有全排列。上例顯示了輸出的前10行。

【運行時限】要求每次運行時間限制在20秒之內。超出該時間則認為程序錯誤。提示:當N增大時,運行時間將急劇增加。在編程時要注意盡量優化算法,提高運行效率。

【評分標準】該題要求輸出若干行整數。

二、代碼

#include<stdio.h> int N; int i,j; int jiecheng[11]; int output[10];int factorial(){jiecheng[0]=1;int i;for(i=1;i<10;i++){jiecheng[i]=i*jiecheng[i-1];} }void print(){int i=0;for(i=0;i<N-1;i++)printf("%d ",output[i]);printf("%d\n",output[i]); }void find(){for(i=N-2;i>=0;i--){if(output[i]<output[i+1])break;}int k1=i;int temp_low=i+1;for(i=k1+1;i<N;i++){if(output[i]>output[k1]&&output[i]<output[temp_low])temp_low=i;}int temp;temp=output[k1];output[k1]=output[temp_low];output[temp_low]=temp;for(j=k1+1,i=N-1;i>j;i--,j++){temp=output[i];output[i]=output[j];output[j]=temp;} }int main(){factorial();scanf("%d",&N);int i;for(i=0;i<N;i++){output[i]=i+1;}print();for(i=1;i<jiecheng[N];i++){find();print();} }

三、算法

這篇博客講的比較詳細全排列的實現方法–遞歸&字典序.
以數列p0p1…pn-1pn為例,具體算法思想分為以下4個步驟:
i)從數列右邊開始,找到第一個小于它右邊的數,即找到一個j,滿足j=max{i|pi<pi+1}
ii)然后從pj+1開始,從pj+1~pn的范圍里面大于pj的數之間,挑出最小的數,記為pk
iii)調換pj和pk的位置,這時候這個數列就變成了p0p1…pj-1pkpj+1…pk-1pjpk+1…pn-1pn
iv)把pj+1…pk-1pjpk+1…pn-1pn逆序,得到的p0p1…pj-1pkpnpn-1…pj+1即為當前數列的下一個數列
為什么可以這樣子呢,我們把p0~pn拆分成兩部分,p0~pj,pj+1~pn,算法步驟1和2就保證了找到剛好比p0~pj的下一個數列,然后我們只需要確保j+1~n最小即可;由算法步驟1可知,j+1~n是降序排列的,即使p[j],p[k]調換位置后也是如此,所以在算法步驟4里面對后面這段逆序,就使得j+1~n 變成了升序,也就是字典序最小

總結

以上是生活随笔為你收集整理的C语言实现数字全排列的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。