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 }
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[ ]: