ACM 求全排列(字典序、邻位对换、递增进位制数,递减进位制数)

字典序:(联合康托展开就也可以按照中介数求)

邻位对换、递增进位制数,递减进位制数:具体的实现和算法讲解如下:

代码。。C++版的实现并不好。。因为是挨个向后找的,如果K很大的时候会超时,不过。。。思路是这样。。。,第二版C++没有完成。。。因为不想写了,思路很简单,一次加减K就可以了

python代码直接给出,很完美

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<vector>
  4 #include<algorithm>
  5
  6 using namespace std;
  7 void Swap(int &a, int &b)
  8 {
  9     a == b ? 0 : a ^= b ^= a ^= b;
 10 }
 11 void Print(int A[],int n)
 12 {
 13     for (int i = 0; i < n; i++)
 14     {
 15         printf("%d%c", A[i], i == n - 1 ? ‘\n‘ : ‘ ‘);
 16     }
 17 }
 18 //阶乘
 19 int factorial(int x) { return x > 1 ? x*factorial(x - 1) : 1; }
 20 //字典序法
 21 void Reverse(int A[],int a,int b)//反转
 22 {
 23     while (a < b)
 24     {
 25         Swap(A[a], A[b]);
 26         a++;
 27         b--;
 28     }
 29 }
 30 bool my_next_permutation(int A[], int n)
 31 {
 32     int i = n - 2;
 33     while ((A[i + 1] <= A[i])&&i>=0)i--;
 34     if (i<0)
 35     {
 36         Reverse(A,0,n-1);
 37         return false;
 38     }
 39     else
 40     {
 41         int j = i+1;
 42         while ((A[j] > A[i])&&j<n)j++;
 43         Swap(A[j-1], A[i]);
 44         Reverse(A ,i+1 , n-1);
 45         return true;
 46     }
 47 }
 48 bool my_prev_permutation(int A[], int n)
 49 {
 50     int i = n - 2;
 51     while ((A[i + 1] >= A[i])&&i>=0)i--;
 52     if (i<0)
 53     {
 54         Reverse(A,0,n-1);
 55         return false;
 56     }
 57     else
 58     {
 59         int j = i+1;
 60         while ((A[j] < A[i])&&j<n)j++;
 61         Swap(A[j-1], A[i]);
 62         Reverse(A ,i+1 , n-1);
 63         return true;
 64     }
 65 }
 66 //中介数 递增
 67 int* get_permutation_medium_plus(int A[], int n)//求递增进位制数
 68 {
 69     int* temp = new int[n];
 70     for (int i = 0; i < n; i++)
 71     {
 72         temp[n-A[i]] = 0;
 73         for (int j = i + 1; j <= n - 1; j++)
 74         {
 75             if (A[j] < A[i])
 76             {
 77                 temp[n-A[i]]++;
 78             }
 79         }
 80     }
 81     return temp;
 82 }
 83 int* get_permutation_plus(int medium[], int n)
 84 {
 85     int* temp = new int[n];
 86     memset(temp, 0, n * sizeof(int));
 87     for (int i = 0; i < n; i++)
 88     {
 89         int empty = -1,j=n;//防止末尾已经被占的情况故提前一位
 90         while (empty < medium[i] && j >= 0)
 91         {
 92             j--;
 93             if (temp[j] <= 0)
 94             {
 95                 empty++;
 96             }
 97         }
 98         temp[j] = n - i;
 99     }
100     return temp;
101 }
102 void next_permutation_increas_medium_plus(int A[],int n)
103 {
104     int* mid = get_permutation_medium_plus(A,n);
105     int last_ = n-1;
106     while(1){
107         if(mid[last_]+1<n-last_){
108             mid[last_]++;
109             break;
110         }
111         mid[last_] = 0;
112         last_--;
113     }
114     int* anstm = get_permutation_plus(mid, n);
115     //Print(anstm,n);
116     for(int i = 0; i < n; i++) A[i] = anstm[i];
117     return;
118 }
119 void prev_permutation_increas_medium_plus(int A[],int n)
120 {
121     int* mid = get_permutation_medium_plus(A,n);
122     int last_ = n-1;
123     while(1){
124         if(mid[last_]-1>=0){
125             mid[last_]--;
126             break;
127         }
128         mid[last_] = n-last_-1;
129         last_--;
130     }
131     int* anstm = get_permutation_plus(mid, n);
132     //Print(anstm,n);
133     for(int i = 0; i < n; i++) A[i] = anstm[i];
134     //Print(get_permutation_plus(mid, n),n);
135     return;
136 }
137 //递减
138 int* get_permutation_medium_sub(int A[], int n)//求递减进位制数
139 {
140     int* temp = new int[n];
141     for (int i = 0; i < n; i++)
142     {
143         temp[n-A[i]] = 0;
144         for (int j = i + 1; j <= n - 1; j++)
145         {
146             if (A[j] < A[i])
147             {
148                 temp[n-A[i]]++;
149             }
150         }
151     }
152     Reverse(temp,0,n-1);
153     return temp;
154 }
155 int* get_permutation_sub(int medium[], int n)
156 {
157     int* temp = new int[n];
158     memset(temp, 0, n * sizeof(int));
159     for (int i = 0; i < n; i++)
160     {
161         int empty = -1, j=n;//防止末尾已经被占的情况故提前一位
162         while (empty < medium[n-i-1] && j >= 0)
163         {
164             j--;
165             if (temp[j] <= 0)
166             {
167                 empty++;
168             }
169         }
170         temp[j] = n - i;
171     }
172     return temp;
173 }
174 void next_permutation_increas_medium_sub(int A[],int n)
175 {
176     int* mid = get_permutation_medium_sub(A,n);
177     //Print(mid,n);
178     int last_ = 1;
179     while(1){
180         if(mid[n-last_]+1<n-last_+1){
181             mid[n-last_]++;
182             break;
183         }
184         mid[n-last_] = 0;
185         last_++;
186     }
187     int* anstm = get_permutation_sub(mid, n);
188     //Print(mid,n);
189     for(int i = 0; i < n; i++) A[i] = anstm[i];
190     return;
191 }
192 void prev_permutation_increas_medium_sub(int A[],int n)
193 {
194     int* mid = get_permutation_medium_sub(A,n);
195     //Print(mid,n);
196     int last_ = 1;
197     while(1){
198         if(mid[n-last_]-1>=0){
199             mid[n-last_]--;
200             break;
201         }
202         mid[n-last_] = n-last_;
203         last_++;
204     }
205     int* anstm = get_permutation_sub(mid, n);
206     //Print(anstm,n);
207     for(int i = 0; i < n; i++) A[i] = anstm[i];
208     //Print(get_permutation_plus(mid, n),n);
209     return;
210 }
211 //邻位对换法
212 int my_find(int A[],int n, int key){
213     for(int i = 0; i < n; i++){
214         if(A[i]==key) return i;
215     }
216     return -1;
217 }
218 int* get_permutation_medium_neighbor(int A[], int dirct[], int n)//求递减进位制数
219 {
220     //dirct[]标记方向,-1向左 1向右
221     int* temp = new int[n];
222     temp[0] = 0;
223     dirct[0] = 0;
224     for(int i = 2; i <= n; i++){
225         int id_ = my_find(A,n,i);
226         if(i==2) dirct[i-1] = -1;
227         else if(i%2==1){
228             if(temp[i-2]%2==1)dirct[i-1] = 1;
229             else dirct[i-1]=-1;
230         }
231         else if(i%2==0){
232             if((temp[i-2]+temp[i-3])%2==1) dirct[i-1] = 1;
233             else dirct[i-1]=-1;
234         }
235         int j = id_;
236         int bi_ = 0;
237         while(j < n && j>=0){
238             if(A[j]<i) bi_++;
239             j += -dirct[i-1]*1;
240         }
241         temp[i-1] = bi_;
242     }
243     return temp;
244 }
245 int* get_permutation_neighbor(int medium[], int dirct[] ,int n)
246 {
247     int* temp = new int[n];
248     for(int i = 0; i < n; i++) temp[i] = 1;
249     for (int i = 1; i < n; i++)
250     {
251         if((n-i+1)==2) dirct[n-i]=-1;
252         else if((n-i+1)%2==1){
253             if(medium[n-i-1]%2==1) dirct[n-i]=1;
254             else dirct[n-i]=-1;
255         }
256         else if((n-i+1)%2==0){
257             if((medium[n-i-1] + medium[n-i-2])%2==1) dirct[n-i] = 1;
258             else dirct[n-i] = -1;
259         }
260         if(dirct[n-i] == -1){
261             int j = n-1;int empty = 0;
262             while(empty <= medium[n-i]&&j>=0){
263                 if(temp[j]==1) empty++;
264                 j--;
265             }
266             temp[j+1] = n-i+1;
267         }
268         else{
269             int j = 0;int empty = 0;
270             while(empty <= medium[n-i]&&j<n){
271                 if(temp[j]==1) empty++;
272                 j++;
273             }
274             temp[j-1] = n-i+1;
275         }
276         //Print(temp,n);
277     }
278     //Print(medium,n);
279     //Print(dirct,n);
280     return temp;
281 }
282 void next_permutation_increas_medium_neighbor(int A[],int dirct[],int n)
283 {
284     int* mid = get_permutation_medium_neighbor(A,dirct,n);
285     //Print(mid,n);
286     //Print(dirct,n);
287     int last_ = 1;
288     while(1){
289         if(mid[n-last_]+1<n-last_+1){
290             mid[n-last_]++;
291             break;
292         }
293         mid[n-last_] = 0;
294         last_++;
295     }
296     int* anstm = get_permutation_neighbor(mid,dirct, n);
297     //Print(mid,n);
298     for(int i = 0; i < n; i++) A[i] = anstm[i];
299     return;
300 }
301 void prev_permutation_increas_medium_neighbor(int A[],int dirct[],int n)
302 {
303     int* mid = get_permutation_medium_neighbor(A,dirct,n);
304     //Print(mid,n);
305     int last_ = 1;
306     while(1){
307         if(mid[n-last_]-1>=0){
308             mid[n-last_]--;
309             break;
310         }
311         mid[n-last_] = n-last_;
312         last_++;
313     }
314     int* anstm = get_permutation_neighbor(mid, dirct,n);
315     //Print(anstm,n);
316     for(int i = 0; i < n; i++) A[i] = anstm[i];
317     //Print(get_permutation_plus(mid, n),n);
318     return;
319 }
320
321
322
323 int main()
324 {
325     int n,type,k;
326     while(~scanf("%d%d%d",&n,&type,&k)){
327         int tm[n];
328         for(int i = 0; i < n; i++){
329             scanf("%d",&tm[i]);
330         }
331         if(type==1){
332             if(k>=0){
333                 while(k--) next_permutation(tm,tm+n);
334                 Print(tm,n);
335             }
336             else{
337                 k = -k;
338                 while(k--) prev_permutation(tm,tm+n);
339                 Print(tm,n);
340             }
341             /*下面自己写的实现竟然超时了,气人
342             if(k>=0){
343                 while(k--) my_next_permutation(tm,n);
344                 Print(tm,n);
345             }
346             else{
347                 k = -k;
348                 while(k--) my_prev_permutation(tm,n);
349                 Print(tm,n);
350             }
351             */
352         }
353         else if(type==2){
354             if(k>=0){
355                 while(k--) next_permutation_increas_medium_plus(tm,n);
356                 Print(tm,n);
357             }
358             else{
359                 k = -k;
360                 while(k--) prev_permutation_increas_medium_plus(tm,n);
361                 Print(tm,n);
362             }
363         }
364         else if(type==3){
365             if(k>=0){
366                 while(k--) next_permutation_increas_medium_sub(tm,n);
367                 Print(tm,n);
368             }
369             else{
370                 k = -k;
371                 while(k--) prev_permutation_increas_medium_sub(tm,n);
372                 Print(tm,n);
373             }
374         }
375         else{
376             int dict[n];
377             if(k>=0){
378                 while(k--) next_permutation_increas_medium_neighbor(tm,dict,n);
379                 Print(tm,n);
380             }
381             else{
382                 k = -k;
383                 while(k--) prev_permutation_increas_medium_neighbor(tm,dict,n);
384                 Print(tm,n);
385             }
386         }
387     }
388     return 0;
389 }

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<vector>
  4 #include<algorithm>
  5 #include<cmath>
  6
  7 using namespace std;
  8 void Swap(int &a, int &b)
  9 {
 10     a == b ? 0 : a ^= b ^= a ^= b;
 11 }
 12 void Print(int A[],int n)
 13 {
 14     for (int i = 0; i < n; i++)
 15     {
 16         printf("%d%c", A[i], i == n - 1 ? ‘\n‘ : ‘ ‘);
 17     }
 18 }
 19 //阶乘
 20 int factorial(int x) { return x > 1 ? x*factorial(x - 1) : 1; }
 21 //字典序法
 22 void Reverse(int A[],int a,int b)//反转
 23 {
 24     while (a < b)
 25     {
 26         Swap(A[a], A[b]);
 27         a++;
 28         b--;
 29     }
 30 }
 31 bool my_next_permutation(int A[], int n)
 32 {
 33     int i = n - 2;
 34     while ((A[i + 1] <= A[i])&&i>=0)i--;
 35     if (i<0)
 36     {
 37         Reverse(A,0,n-1);
 38         return false;
 39     }
 40     else
 41     {
 42         int j = i+1;
 43         while ((A[j] > A[i])&&j<n)j++;
 44         Swap(A[j-1], A[i]);
 45         Reverse(A ,i+1 , n-1);
 46         return true;
 47     }
 48 }
 49 bool my_prev_permutation(int A[], int n)
 50 {
 51     int i = n - 2;
 52     while ((A[i + 1] >= A[i])&&i>=0)i--;
 53     if (i<0)
 54     {
 55         Reverse(A,0,n-1);
 56         return false;
 57     }
 58     else
 59     {
 60         int j = i+1;
 61         while ((A[j] < A[i])&&j<n)j++;
 62         Swap(A[j-1], A[i]);
 63         Reverse(A ,i+1 , n-1);
 64         return true;
 65     }
 66 }
 67 //用中介数求字典序法
 68
 69
 70 //中介数 递增
 71 int* get_permutation_medium_plus(int A[], int n)//求递增进位制数
 72 {
 73     int* temp = new int[n];
 74     for (int i = 0; i < n; i++)
 75     {
 76         temp[n-A[i]] = 0;
 77         for (int j = i + 1; j <= n - 1; j++)
 78         {
 79             if (A[j] < A[i])
 80             {
 81                 temp[n-A[i]]++;
 82             }
 83         }
 84     }
 85     return temp;
 86 }
 87 int* get_permutation_plus(int medium[], int n)
 88 {
 89     int* temp = new int[n];
 90     memset(temp, 0, n * sizeof(int));
 91     for (int i = 0; i < n; i++)
 92     {
 93         int empty = -1,j=n;//防止末尾已经被占的情况故提前一位
 94         while (empty < medium[i] && j >= 0)
 95         {
 96             j--;
 97             if (temp[j] <= 0)
 98             {
 99                 empty++;
100             }
101         }
102         temp[j] = n - i;
103     }
104     return temp;
105 }
106 void next_permutation_increas_medium_plus(int A[],int n,int k)
107 {
108     int* mid = get_permutation_medium_plus(A,n);
109     int last_ = n-1;
110     while(1){
111         if(mid[last_]+k<n-last_){
112             mid[last_] += k;
113             break;
114         }
115         int dim = (mid[last_]+k);
116         mid[last_] = (mid[last_]+k)%(n-last_);
117         k = dim/(n-last_);
118         last_--;
119     }
120     int* anstm = get_permutation_plus(mid, n);
121     //Print(anstm,n);
122     for(int i = 0; i < n; i++) A[i] = anstm[i];
123     return;
124 }
125
126 void prev_permutation_increas_medium_plus(int A[],int n,int k)
127 {
128     int* mid = get_permutation_medium_plus(A,n);
129     int last_ = n-1;
130     while(1){
131         if(mid[last_]-k>=0){
132             mid[last_]-=k;
133             break;
134         }
135         int dim = (k-mid[last_]);
136         int c = ceil(double(dim)/(n-last_));
137         mid[last_] = c*(n-last_)-(k-mid[last_]);
138         k = c;
139         last_--;
140     }
141     int* anstm = get_permutation_plus(mid, n);
142     //Print(anstm,n);
143     for(int i = 0; i < n; i++) A[i] = anstm[i];
144     //Print(get_permutation_plus(mid, n),n);
145     return;
146 }
147
148 //递减
149 int* get_permutation_medium_sub(int A[], int n)//求递减进位制数
150 {
151     int* temp = new int[n];
152     for (int i = 0; i < n; i++)
153     {
154         temp[n-A[i]] = 0;
155         for (int j = i + 1; j <= n - 1; j++)
156         {
157             if (A[j] < A[i])
158             {
159                 temp[n-A[i]]++;
160             }
161         }
162     }
163     Reverse(temp,0,n-1);
164     return temp;
165 }
166 int* get_permutation_sub(int medium[], int n)
167 {
168     int* temp = new int[n];
169     memset(temp, 0, n * sizeof(int));
170     for (int i = 0; i < n; i++)
171     {
172         int empty = -1, j=n;//防止末尾已经被占的情况故提前一位
173         while (empty < medium[n-i-1] && j >= 0)
174         {
175             j--;
176             if (temp[j] <= 0)
177             {
178                 empty++;
179             }
180         }
181         temp[j] = n - i;
182     }
183     return temp;
184 }
185 void next_permutation_increas_medium_sub(int A[],int n,int k)
186 {
187     int* mid = get_permutation_medium_sub(A,n);
188     //Print(mid,n);
189     int last_ = 1;
190     while(1){
191         if(mid[n-last_]+k<n-last_+1){
192             mid[n-last_] += k;
193             break;
194         }
195         int dim = (mid[n-last_]+k);
196         mid[n-last_] = (mid[n-last_]+k)%(n-last_+1);
197         k = dim/(n-last_+1);
198         last_++;
199     }
200     int* anstm = get_permutation_sub(mid, n);
201     //Print(mid,n);
202     for(int i = 0; i < n; i++) A[i] = anstm[i];
203     return;
204 }
205 void prev_permutation_increas_medium_sub(int A[],int n,int k)
206 {
207     int* mid = get_permutation_medium_sub(A,n);
208     //Print(mid,n);
209     int last_ = 1;
210     while(1){
211         if(mid[n-last_]-k>=0){
212             mid[n-last_]-=k;
213             break;
214         }
215         int dim = (k-mid[n-last_]);
216         int c = ceil(double(dim)/(n-last_+1));
217         mid[n-last_] = c*(n-last_+1)-(k-mid[n-last_]);
218         k = c;
219         last_++;
220     }
221     int* anstm = get_permutation_sub(mid, n);
222     //Print(anstm,n);
223     for(int i = 0; i < n; i++) A[i] = anstm[i];
224     //Print(get_permutation_plus(mid, n),n);
225     return;
226 }
227 //邻位对换法
228 int my_find(int A[],int n, int key){
229     for(int i = 0; i < n; i++){
230         if(A[i]==key) return i;
231     }
232     return -1;
233 }
234 int* get_permutation_medium_neighbor(int A[], int dirct[], int n)//求递减进位制数
235 {
236     //dirct[]标记方向,-1向左 1向右
237     int* temp = new int[n];
238     temp[0] = 0;
239     dirct[0] = 0;
240     for(int i = 2; i <= n; i++){
241         int id_ = my_find(A,n,i);
242         if(i==2) dirct[i-1] = -1;
243         else if(i%2==1){
244             if(temp[i-2]%2==1)dirct[i-1] = 1;
245             else dirct[i-1]=-1;
246         }
247         else if(i%2==0){
248             if((temp[i-2]+temp[i-3])%2==1) dirct[i-1] = 1;
249             else dirct[i-1]=-1;
250         }
251         int j = id_;
252         int bi_ = 0;
253         while(j < n && j>=0){
254             if(A[j]<i) bi_++;
255             j += -dirct[i-1]*1;
256         }
257         temp[i-1] = bi_;
258     }
259     return temp;
260 }
261 int* get_permutation_neighbor(int medium[], int dirct[] ,int n)
262 {
263     int* temp = new int[n];
264     for(int i = 0; i < n; i++) temp[i] = 1;
265     for (int i = 1; i < n; i++)
266     {
267         if((n-i+1)==2) dirct[n-i]=-1;
268         else if((n-i+1)%2==1){
269             if(medium[n-i-1]%2==1) dirct[n-i]=1;
270             else dirct[n-i]=-1;
271         }
272         else if((n-i+1)%2==0){
273             if((medium[n-i-1] + medium[n-i-2])%2==1) dirct[n-i] = 1;
274             else dirct[n-i] = -1;
275         }
276         if(dirct[n-i] == -1){
277             int j = n-1;int empty = 0;
278             while(empty <= medium[n-i]&&j>=0){
279                 if(temp[j]==1) empty++;
280                 j--;
281             }
282             temp[j+1] = n-i+1;
283         }
284         else{
285             int j = 0;int empty = 0;
286             while(empty <= medium[n-i]&&j<n){
287                 if(temp[j]==1) empty++;
288                 j++;
289             }
290             temp[j-1] = n-i+1;
291         }
292         //Print(temp,n);
293     }
294     //Print(medium,n);
295     //Print(dirct,n);
296     return temp;
297 }
298 void next_permutation_increas_medium_neighbor(int A[],int dirct[],int n,int k)
299 {
300     int* mid = get_permutation_medium_neighbor(A,dirct,n);
301     //Print(mid,n);
302     //Print(dirct,n);
303     int last_ = 1;
304     while(1){
305         if(mid[n-last_]+k<n-last_+1){
306             mid[n-last_] += k;
307             break;
308         }
309         int dim = (mid[n-last_]+k);
310         mid[n-last_] = (mid[n-last_]+k)%(n-last_+1);
311         k = dim/(n-last_+1);
312         last_++;
313     }
314     int* anstm = get_permutation_neighbor(mid,dirct, n);
315     //Print(mid,n);
316     for(int i = 0; i < n; i++) A[i] = anstm[i];
317     return;
318 }
319 void prev_permutation_increas_medium_neighbor(int A[],int dirct[],int n,int k)
320 {
321     int* mid = get_permutation_medium_neighbor(A,dirct,n);
322     //Print(mid,n);
323     int last_ = 1;
324     while(1){
325         if(mid[n-last_]-k>=0){
326             mid[n-last_]-=k;
327             break;
328         }
329         int dim = (k-mid[n-last_]);
330         int c = ceil(double(dim)/(n-last_+1));
331         mid[n-last_] = c*(n-last_+1)-(k-mid[n-last_]);
332         k = c;
333         last_++;
334     }
335     int* anstm = get_permutation_neighbor(mid, dirct,n);
336     //Print(anstm,n);
337     for(int i = 0; i < n; i++) A[i] = anstm[i];
338     //Print(get_permutation_plus(mid, n),n);
339     return;
340 }
341
342
343
344 int main()
345 {
346     int n,type,k;
347     while(~scanf("%d%d%d",&n,&type,&k)){
348         int tm[n];
349         for(int i = 0; i < n; i++){
350             scanf("%d",&tm[i]);
351         }
352
353         if(type==1){
354            /* if(k>=0){
355                 my_next_permutation(tm,n,k);
356                 Print(tm,n);
357             }
358             else{
359                 k = -k;
360                 my_prev_permutation(tm,n,k);
361                 Print(tm,n);
362             }
363             下面自己写的实现竟然超时了,气人
364             if(k>=0){
365                 while(k--) my_next_permutation(tm,n);
366                 Print(tm,n);
367             }
368             else{
369                 k = -k;
370                 while(k--) my_prev_permutation(tm,n);
371                 Print(tm,n);
372             }*/
373
374         }
375
376         else if(type==2){
377             if(k>=0){
378                 next_permutation_increas_medium_plus(tm,n,k);
379                 Print(tm,n);
380             }
381             else{
382                 k = -k;
383                 prev_permutation_increas_medium_plus(tm,n,k);
384                 Print(tm,n);
385             }
386
387         }
388         else if(type==3){
389             if(k>=0){
390                 next_permutation_increas_medium_sub(tm,n,k);
391                 Print(tm,n);
392             }
393             else{
394                 k = -k;
395                 prev_permutation_increas_medium_sub(tm,n,k);
396                 Print(tm,n);
397             }
398         }
399         else{
400             int dict[n];
401             if(k>=0){
402                 next_permutation_increas_medium_neighbor(tm,dict,n,k);
403                 Print(tm,n);
404             }
405             else{
406                 k = -k;
407                 prev_permutation_increas_medium_neighbor(tm,dict,n,k);
408                 Print(tm,n);
409             }
410         }
411     }
412     return 0;
413 }

C++ 修改版

  1 #!/usr/bin/env python
  2 # coding: utf-8
  3
  4 # In[2]:
  5
  6
  7 def dictionary(a,b):
  8     zhongjie=[]
  9     for i in range(len(b)-1):
 10         sum0=0
 11         for j in b[(i+1):]:
 12             if j<b[i]:
 13                 sum0+=1
 14         zhongjie.append(sum0)
 15     xushu=zhongjie_to_ten(zhongjie)+a[2]
 16     zhongjie=ten_to_zhongjie(a[0],xushu)
 17     result=zhongjie_to_pailie(zhongjie)
 18     return result
 19
 20
 21 # In[3]:
 22
 23
 24 def increase(a,b):
 25     temp=inc_paixu_zhongjie(b)
 26     temp=zhongjie_to_ten(temp)+a[2]
 27     temp=ten_to_zhongjie(a[0],temp)
 28     result=inc_zhongjie_paixu(temp)
 29     result.reverse()
 30     return result
 31
 32
 33 # In[4]:
 34
 35
 36 def decrease(a,b):
 37     zhongjie=inc_paixu_zhongjie(b)
 38     zhongjie.reverse()
 39     xuhao=int(dec_zhongjie_ten(zhongjie))
 40     xuhao+=int(a[2])
 41     zhongjie=dec_ten_zhongjie(a[0],xuhao)
 42     zhongjie.reverse()
 43     result=inc_zhongjie_paixu(zhongjie)
 44     result.reverse()
 45     return result
 46
 47
 48 # In[30]:
 49
 50
 51 def exchange(a,b):
 52     zhongjie=exc_paixu_zhongjie(b)
 53     xuhao=int(dec_zhongjie_ten(zhongjie))
 54     xuhao1=int(a[2])+xuhao
 55     zhongjie=dec_ten_zhongjie(a[0],xuhao1)
 56     result=exc_zhongjie_paixu(zhongjie)
 57     return result
 58
 59
 60 # In[6]:
 61
 62
 63 ##exchange
 64 def exc_paixu_zhongjie(b):
 65     direction=[0]*len(b)
 66     zhongjie=[0]*(len(b)-1)
 67     ##向左为0,向右为1
 68     sum0=0
 69     for i in b[(b.index(2)):]:
 70         if i<2:
 71             sum0+=1
 72     zhongjie[0]=sum0
 73     for i in range(3,len(b),2):
 74         ##奇数位
 75         direction[b.index(i)]=zhongjie[i-3]%2
 76         if direction[b.index(i)]:
 77             sum0=0
 78             for j in b[0:(b.index(i))]:
 79                 if j<i:
 80                     sum0+=1
 81             zhongjie[i-2]=sum0
 82         else:
 83             sum0=0
 84             for j in b[(b.index(i)):]:
 85                 if j<i:
 86                     sum0+=1
 87             zhongjie[i-2]=sum0
 88         ##偶数位
 89         direction[b.index(i+1)]=(zhongjie[i-3]+zhongjie[i-2])%2
 90         if direction[b.index(i+1)]:
 91             sum0=0
 92             for j in b[0:(b.index(i+1))]:
 93                 if j<(i+1):
 94                     sum0+=1
 95             zhongjie[i-1]=sum0
 96         else:
 97             sum0=0
 98             for j in b[(b.index(i+1)):]:
 99                 if j<(i+1):
100                     sum0+=1
101             zhongjie[i-1]=sum0
102     if len(b)%2==1:
103         direction[b.index(len(b))]=zhongjie[len(b)-3]%2
104         if direction[b.index(len(b))]:
105             sum0=0
106             for j in b[0:(b.index(len(b)))]:
107                 if j<len(b):
108                     sum0+=1
109             zhongjie[len(b)-2]=sum0
110         else:
111             sum0=0
112             for j in b[(b.index(len(b))):]:
113                 if j<len(b):
114                     sum0+=1
115             zhongjie[len(b)-2]=sum0
116     return zhongjie
117
118 def exc_zhongjie_paixu(zhongjie):
119     paixu=[1]*(len(zhongjie)+1)
120     for i in range(len(paixu),2,-1):
121         if i%2==1:##奇数
122             if zhongjie[i-3]%2==1:##向右
123
124                 sum0=0
125                 for j in range(len(paixu)):
126                     sum0+=(paixu[j]==1)
127                     if sum0==zhongjie[i-2]+1:
128                         paixu[j]=i
129                         break
130             else:#向左
131                 paixu.reverse()
132                 sum0=0
133                 for j in range(len(paixu)):
134                     sum0+=(paixu[j]==1)
135                     if sum0==zhongjie[i-2]+1:
136                         paixu[j]=i
137                         paixu.reverse()
138                         break
139
140         else:#偶数
141             if (zhongjie[i-4]+zhongjie[i-3])%2==1:##向右
142                 sum0=0
143                 for j in range(len(paixu)):
144                     sum0+=(paixu[j]==1)
145                     if sum0==zhongjie[i-2]+1:
146                         paixu[j]=i
147                         break
148             else:#向左
149                 paixu.reverse()
150                 sum0=0
151                 for j in range(len(paixu)):
152                     sum0+=(paixu[j]==1)
153                     if sum0==zhongjie[i-2]+1:
154                         paixu[j]=i
155                         paixu.reverse()
156                         break
157     if zhongjie[0]==0:
158         paixu.reverse()
159     paixu[paixu.index(1)]=2
160     if zhongjie[0]==0:
161         paixu.reverse()
162     return paixu
163
164
165 # In[58]:
166
167
168 ###decrease###
169 def dec_zhongjie_ten(zhongjie):
170     sum0=0
171     for i in range(len(zhongjie)):
172         sum0+=zhongjie[i]*int(jiecheng(len(zhongjie)+1))//int(jiecheng(i+2))
173     return sum0
174 def idec_zhongjie_ten(zhongjie):
175     sum0=zhongjie[0]
176     for i in range(3,len(zhongjie)+2):
177         sum0=sum0*i+zhongjie[i-2]
178     return sum0
179 def dec_ten_zhongjie(n,xuhao):
180     abs_n=int(xuhao)
181     out=[0]*(n-1)
182     for i in range(n,1,-1):
183         out[i-2]=abs_n%i
184         abs_n=abs_n//i
185     return out
186
187
188 # In[8]:
189
190
191 ###increase###
192 def inc_paixu_zhongjie(b):##增序排序到中介数
193     result=[]
194     for i in range(len(b),1,-1):
195         sum0=0
196         for j in b[(b.index(i)):]:
197             if j<i:
198                 sum0+=1
199         result.append(sum0)
200     return result
201 def error(zhongjie):
202     paixu=[1]*(len(zhongjie)+1)##逆序数,最后倒置
203     for i in range(len(zhongjie)):
204         sum=0
205         for j in range(len(paixu)):
206             if paixu[j]==1:
207                 sum+=1
208             if sum==zhongjie[i] and paixu[j+1]==1:
209                 paixu[j+1]=len(zhongjie)+1-i
210                 break
211             if zhongjie[i]==0 and paixu[j]==1:
212                 paixu[j]=len(zhongjie)+1-i
213                 break
214     paixu.reverse()
215     return  paixu
216 def inc_zhongjie_paixu(zhongjie):
217     paixu=[1]*(len(zhongjie)+1)
218     for i in range(len(zhongjie)):
219         sum0=0
220         for j in range(len(paixu)):
221             if paixu[j]==1:
222                 if sum0==zhongjie[i]:
223                     paixu[j]=len(paixu)-i
224                     break
225                 else:
226                     sum0+=1
227     paixu.reverse
228     return paixu
229
230
231 # In[32]:
232
233
234 #######字典序#######
235 def jiecheng(n):##阶乘
236     if n==0 or n==1 or n>20:
237         return 1
238     else:
239         return int(n*jiecheng(n-1))
240 def ten_to_zhongjie(n,ten):##十进制转换中介数
241     abs_n=abs(ten)
242     out=[]
243     for i in range(n-1,0,-1):
244         zheng=abs_n//jiecheng(i)
245         abs_n=abs_n%jiecheng(i)
246         out.append(zheng)
247     return out
248 def zhongjie_to_ten(zhongjie):##中介数转换10进制
249     sum=0
250     for  i in range(len(zhongjie)):
251         sum=sum+zhongjie[-(i+1)]*jiecheng(i+1)
252     return sum
253 def zhongjie_to_pailie(zhongjie):##中介数转排列
254     pailie=[]
255     for i in range(len(zhongjie)):
256         temp=sorted(pailie)
257         pailie_new=zhongjie[i]+1
258         for j in temp:
259             if j<=pailie_new:
260                 pailie_new=pailie_new+1
261         pailie.append(pailie_new)
262     for i in range(len(pailie)+1):
263         if (i+1) not in pailie:
264             pailie.append(i+1)
265     return pailie
266
267
268 # In[33]:
269
270
271 #a=input()
272 #b=input()
273 ##初始化
274 #a=a.split()
275 #b=b.split()
276 #for i in range(len(a)):
277  #   a[i]=int(a[i])
278 #for i in range(a[0]):
279   #  b[i]=int(b[i])
280 a=list(map(int,input().split(" ")[:3]))
281 b=list(map(int,input().split(" ")[:a[0]]))
282     ##分类运算
283 if a[1]==1:
284     output=dictionary(a,b)
285 elif a[1]==2:
286     output=increase(a,b)
287 elif a[1]==3:
288     output=decrease(a,b)
289 elif a[1]==4:
290     output=exchange(a,b)
291 else :
292     output=b
293
294 #输出
295 for i in range(a[0]):
296     output[i]=str(output[i])
297 print(" ".join(output))
298
299
300 # In[ ]:

原文地址:https://www.cnblogs.com/shanyr/p/11644808.html

时间: 2024-09-30 02:15:02

ACM 求全排列(字典序、邻位对换、递增进位制数,递减进位制数)的相关文章

PermutationsUnique,求全排列,去重

问题描述:给定一个数组,数组里面有重复元素,求全排列. 算法分析:和上一道题一样,只不过要去重. 3 import java.util.ArrayList; 4 import java.util.HashSet; 5 import java.util.List; 6 import java.util.Set; 7 8 public class PermutationsUnique { 9 public ArrayList<ArrayList<Integer>> permuteUni

字典序排序-求全排列(元素有重复)

思路:数组a的元素分别是1,2,3,3:字典序排序就是找到下一个比1,2,3,3大的数组序列,即1,3,2,3: 步骤如下:1.首先使用Arrays.sort()对待排序数组进行排序:比如输入3213,排序后变成1233:从数组最后一个元素起(即i = 数组长度),将a[i]和a[i-1]比较,找到第一个a[i-1]<a[i]的i-1; 2,此时,a[i]前面可能还存在比a[i-1]大的元素,从数组末尾开始找到第一个比a[i-1]大的元素x,将x和a[i-1]交换,对Arrays.sort(a,

nyoj-366-D的小L(求全排列)

D的小L 时间限制:4000 ms  |  内存限制:65535 KB 难度:2 描述       一天TC的匡匡找ACM的小L玩三国杀,但是这会小L忙着哩,不想和匡匡玩但又怕匡匡生气,这时小L给匡匡出了个题目想难倒匡匡(小L很D吧),有一个数n(0<n<10),写出1到n的全排列,这时匡匡有点囧了,,,聪明的你能帮匡匡解围吗? 输入 第一行输入一个数N(0<N<10),表示有N组测试数据.后面的N行输入多组输入数据,每组输入数据都是一个整数x(0<x<10) 输出 按

求全排列的数学方法(洛谷1088 火星人noip2004普及组第4题)

人类终于登上了火星的土地并且见到了神秘的火星人.人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法.这种交流方法是这样的,首先,火星人把一个非常大的数字告诉人类科学家,科学家破解这个数字的含义后,再把一个很小的数字加到这个大数上面,把结果告诉火星人,作为人类的回答. 火星人用一种非常简单的方式来表示数字――掰手指.火星人只有一只手,但这只手上有成千上万的手指,这些手指排成一列,分别编号为1,2,3…….火星人的任意两根手指都能随意交换位置,他们就是通过这方法计数的. 一

ACM 擅长排列的小明

擅长排列的小明 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 小明十分聪明,而且十分擅长排列计算.比如给小明一个数字5,他能立刻给出1-5按字典序的全排列,如果你想为难他,在这5个数字中选出几个数字让他继续全排列,那么你就错了,他同样的很擅长.现在需要你写一个程序来验证擅长排列的小明到底对不对. 输入 第一行输入整数N(1<N<10)表示多少组测试数据,每组测试数据第一行两个整数 n m (1<n<9,0<m<=n) 输出 在1-n中选取

leetcode31 下一个排列 字典序

数字的字典序就是比大小 先想几个例子  123_>132  1243-> 1324 ,12453-> 12534 1.不可排的序列就是降序序列 2.两个相同长度的串比大小,前面相同,比较第一个长度不同的字符,且越靠后越是比原来串大的小串 因为降序已经不可再排,并且字符越靠后影响越小,于是找到降序序列左侧第一个数字(最靠后)A[i],因为要整体字典序变大就与降序序列中刚好比他大的数字交换 此时得到的字典序比原来大,但是并不是最小的.重新排列A[i+1]--A[len-1],升序排列.这样得

LeetCode46 回溯算法求全排列,这次是真全排列

本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode的26篇文章,我们来实战一下全排列问题. 在之前的文章当中,我们讲过八皇后.回溯法,也提到了全排列,但是毕竟没有真正写过.今天的LeetCode46题正是让我们生成给定元素的全排列. 题意很简单,只有一句话,给定一个没有重复元素的序列,让我们返回这个序列所有的全排列,并且我们不需要考虑这些排列的顺序. 回溯法 我们在之前的文章当中分析过,全排列问题,可以看成是搜索问题,从而近似成八皇后问题.在八皇后问题当中,我们枚

求全排列

参考: 1. STL系列之十 全排列(百度迅雷笔试题) 2. 全排列算法非递归实现和递归实现 (C++) 3. [算法]列车算法 题目要求: 写一个函数, 如 Foo(const char *str), 打印出 str 的全排列, 如 abc 的全排列: abc, acb, bca, dac, cab, cba 一.全排列的递归实现 为方便起见,用123来示例下.123的全排列有123.132.213.231.312.321这六种.首先考虑123和132如何得出:它们的最高位都固定为1(或者说以

求全排列(数组有重复元素和数组无重复元素) 回溯 递归

http://www.cnblogs.com/TenosDoIt/p/3662644.html 无重复元素 http://blog.csdn.net/havenoidea/article/details/12838479 有重复元素