全排列之next_permutation

闲话

 当你要枚举一个数组的全排列时,你可能会暴力 f o r 枚举,有没有感觉写的很累效率又一般呢?
 这时,你就需要 S T L 的某个黑科技: n e x t _ p e r m u t a t i o n

使用方法:

int az[4]={1,2,3,4};
do{
  for(int i=0;i<4;++i){
    printf("%d ", az[i]);
  }
  printf("\n");
}while(next_permutation(az,az+4));


注意:

  • 如果你需要的是全排列,记得给原数组排序。 n e x t _ p e r m u t a t i o n 返回的是第一个比当前序列字典序大的序列。
  • 对已经是字典序最大的序列执行 n e x t _ p e r m u t a t i o n 时它的返回值是 0 ,然后它的字典序会变成最小的那个。而对于非字典序最大的序列它的返回值是 1


例题一:CF908B

人生第一场CFrating赛:GoodBye 2017.

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<ctype.h>
#define N 55
using namespace std;
char ar[N][N], di[2 * N];
int n, m;
bool vis[N][N];
int main(){
  int sx, sy, ex, ey;
  while(~scanf("%d%d", &n, &m)) {
    int cnt=0;
    for(int i = 0; i < n; i++) {
      scanf("%s", ar[i]);
    }
    scanf("%s", di);
    for(int i = 0; i < n; i++) {
      for(int j = 0; j < m; j++) {
        if(ar[i][j] == 'S')sx = i, sy = j;
        if(ar[i][j] == 'E')ex = i, ey = j;
      }
    }
    int ldi = strlen(di);
    int dir[4][2]={0};
    char vo[4]={'A','B','C','D'};
    for(int i=0;i<24;i++) {
      int tx = sx, ty = sy,px,py;
      for(int i=0;i<4;i++){
        if(vo[i]=='A'){
          dir[i][0]=-1,dir[i][1]=0;
        }else if(vo[i]=='B'){
          dir[i][0]=1,dir[i][1]=0;
        }else if(vo[i]=='C'){
          dir[i][0]=0,dir[i][1]=-1;
        }else{
          dir[i][0]=0,dir[i][1]=1;
        }
      }
      for(int i = 0; i < ldi; i++) {
        switch (di[i]) {
          case '0': px=tx+dir[0][0],py=ty+dir[0][1]; break;
          case '1': px=tx+dir[1][0],py=ty+dir[1][1]; break;
          case '2': px=tx+dir[2][0],py=ty+dir[2][1]; break;
          case '3': px=tx+dir[3][0],py=ty+dir[3][1]; break;
          default : break;
        }
        if(px<0||py<0||px>=n||py>=m) break;
        if(ar[px][py]=='#') break;
        if(px==ex&&py==ey){
            cnt++;break;
        }
        tx=px,ty=py;
      }
      next_permutation(vo,vo+4);
    }
    printf("%d\n",cnt);
  }
  return 0;
}


刚水过去一道题

CF814B今天早训的一题

#include<bits/stdc++.h>
#define mme(a,b) memset((a),(b),sizeof((a))) 
#define fuck(x) cout<<"* "<<x<<"\n"
using namespace std;
typedef long long LL;
const int N = 1e6 + 7;
const int INF = 0x3f3f3f3f;

int n, m;
int ar[N], br[N], ans[N], vis[N];

int main(){
  while(~scanf("%d",&n)){
    for(int i=1;i<=n;++i){
      scanf("%d",&ar[i]);
    }
    mme(ans,0);mme(vis,0);
    int az[10],k=0;;
    vector<int> have;
    for(int i=1;i<=n;++i){
      scanf("%d",&br[i]);
      if(ar[i]!=br[i]){
        have.push_back(i);
      }else ans[i]=ar[i];
    }
    for(int i=1;i<=n;++i)vis[ans[i]]=1;
    for(int i=1;i<=n;++i){
      if(vis[i]==0)az[k++]=i;
    }

    sort(az,az+k);
    do{
      int c1 = 0,c2 = 0,tot = have.size();
      for(int i=0;i<tot;++i){
        if(ar[have[i]]!=az[i])c1++;
        if(br[have[i]]!=az[i])c2++;
        ans[have[i]]=az[i];
      }
      if(c1==1&&c2==1)break;
    }while(next_permutation(az,az+k));

    for(int i=1;i<=n;++i){
      printf("%d\n", ans[i]);
    }
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39599067/article/details/81669699