闲话
当你要枚举一个数组的全排列时,你可能会暴力
枚举,有没有感觉写的很累效率又一般呢?
这时,你就需要
的某个黑科技:
使用方法:
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));
注意:
- 如果你需要的是全排列,记得给原数组排序。 返回的是第一个比当前序列字典序大的序列。
- 对已经是字典序最大的序列执行 时它的返回值是 ,然后它的字典序会变成最小的那个。而对于非字典序最大的序列它的返回值是 。
例题一: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;
}