蓝桥杯训练 | 递归与递推 | 01

递归实现指数型枚举

#include<iostream>
using namespace std;

const int N=15+10;
bool st[N];
int n;

void dfs(int u){
    if(u>n){
        for(int i=1;i<=n;i++){
            if(st[i])cout << i << " ";
        }
        cout << endl;
        return;
    }
    st[u]=true,dfs(u+1);
    st[u]=false,dfs(u+1);
}

int main(){
    cin >> n;
    dfs(1);
    
    return 0;
}

递归实现排列型枚举

#include<bits/stdc++.h>
using namespace std;

const int N=9+10;
bool used[N];
vector<int> path;
int n;
int choice[] = {1,2,3,4,5,6,7,8,9};

void dfs(int u){
	if(u==n){
		for(vector<int>::iterator i=path.begin();i!=path.end();i++)
			cout << *i << " ";
		cout << endl;
		return ;
	}
	for(int i=0;i<n;i++){
		if(!used[i]){
			used[i]=true,path.push_back(choice[i]);
			dfs(u+1);
			used[i]=false,path.pop_back();		
		}
	}
}

int main(){
	cin >> n;
	dfs(0);
	
	return 0;
}


简单斐波那契

#include<iostream>
using namespace std;

const int N=46+10;
int q[N];


int main(){
	int n;
	cin >> n;
	q[0]=0,q[1]=1;
	for(int i=2;i<n;i++)q[i]=q[i-1]+q[i-2];
	for(int i=0;i<n;i++)cout << q[i] << " ";
	cout << endl;
	
	return 0;
}

费解的开关

第一行的状态是通过枚举确定的,然后通过第一行的状态来确定下面行的状态,依次类推.

核心: 第一行的操作确定后,第二行的操作也就唯一确定.

#include<bits/stdc++.h>
using namespace std;

const int N=6;
char g[N][N],backup[N][N];

int dx[]={0,1,0,-1,0};
int dy[]={-1,0,1,0,0};

void turn(int x,int y){
    for(int i=0;i<5;i++){
        int tx=x+dx[i],ty=y+dy[i];
        if(tx<0 || tx>=5 || ty<0 || ty>=5)continue;
        g[tx][ty]=g[tx][ty]=='0'?'1':'0';
    }
}

int main(){
    int T;
    cin >> T;
    while(T--){
        for(int i=0;i<5;i++)cin>>g[i];
        int res=1<<30;
        for(int op=0;op<(1<<5);op++){
            memcpy(backup,g,sizeof g);
            int step=0;
            for(int i=0;i<5;i++){
                if(op >> i & 1){
                    turn(0,i),step++;
                }
            }
            for(int i=1;i<5;i++){
                for(int j=0;j<5;j++){
                    if(g[i-1][j]=='0'){
                        turn(i,j),step++;
                    }
                }
            }
            bool success=true;
            for(int i=0;i<5;i++)
                if(g[4][i]=='0'){
                    success=false;
                    break;
                }
            
            if(success && step<=6)res=min(step,res);    
            memcpy(g,backup,sizeof g);
        }
        if(res==1<<30)cout << "-1" << endl;
        else cout << res << endl;
    }
    return 0;
}

递归实现组合型枚举

#include<bits/stdc++.h>
using namespace std;

const int N= 30;
int n,m;
int choice[N];
vector<int> path;
bool used[N];

void dfs(int u,int s){
    if(u+n-s<m)return;
    if(u==m){
        for(int i=0;i<path.size();i++)cout << path[i] << " ";
        cout << endl;
        return;
    }
    for(int i=s;i<n;i++){
        if(!used[i]){
            used[i]=true,path.push_back(choice[i]);
            dfs(u+1,i+1); // 坑
            used[i]=false,path.pop_back();
        }
    }
}

int main(){
    cin >> n >> m;
    for(int i=0;i<=n;i++)choice[i]=i+1;
    dfs(0,0);
    
    return 0;
}

带分数

#include<bits/stdc++.h>
using namespace std;


int n,res;
int choice[]={1,2,3,4,5,6,7,8,9};
vector<int> path;
bool used[20];

int cal(int l,int r){
    int res=0;
    for(int i=l;i<=r;i++)res=res*10+path[i];
    return res;
}


void dfs(int u){
    if(u==9){
        for(int i=0;i<7;i++){
            for(int j=i+1;j<8;j++){
                int a = cal(0,i);
                int b = cal(i+1,j);
                int c = cal(j+1,8);
                if(c*(n-a)==b)res++;
            }
        }   
        return;
    }
    for(int i=0;i<9;i++){
        if(!used[i]){
            used[i]=true,path.push_back(choice[i]);
            dfs(u+1);
            used[i]=false,path.pop_back();
        }
    }
    
}


int main(){
    cin >> n;
    dfs(0);
    cout << res << endl;
    return 0;
}

飞行员兄弟

#include<bits/stdc++.h>
using namespace std;

typedef pair<int,int> PII;


const int N=5;
char g[N][N],backup[N][N];

bool check(){
    for(int i=0;i<4;i++){
        for(int j=0;j<4;j++){
            if(g[i][j]=='+')return false;
        }
    }
    return true;
}


void turn(int x,int y){
    for(int i=0;i<4;i++){
        g[x][i]=g[x][i]=='+'?'-':'+';
        g[i][y]=g[i][y]=='+'?'-':'+';
    }
    g[x][y]=g[x][y]=='+'?'-':'+';
}

int main(){
    for(int i=0;i<4;i++)cin>>g[i];
    vector<PII> res_f;
    for(int op=0;op< (1<<16);op++){
        vector<PII> res_t;
        memcpy(backup,g,sizeof g);
        for(int i=0;i<4;i++){
            for(int j=0;j<4;j++){
                if(op >> (i*4+j) & 1){
                    turn(i,j);
                    res_t.push_back({i,j});
                }
            }
        }
        if(check()){
            if(res_f.empty() || res_f.size() > res_t.size())res_f=res_t;
        }
        
        memcpy(g,backup,sizeof g);
    }
    cout << res_f.size() << endl;
    for(vector<PII>::iterator i=res_f.begin();i!=res_f.end();i++)
        cout <<  i->first + 1 << " " << i->second + 1<< endl;
    
    
    return 0;
}

翻硬币

#include<bits/stdc++.h>
using namespace std;

const int N=110;
char g[N],dest[N],backup[N];

void turn(int x){
    g[x]=g[x]=='*'?'o':'*';
    g[x-1]=g[x-1]=='*'?'o':'*';
}

int main(){
    cin >> g >> dest;
    int len = strlen(g);
    int res_f=1<<30;
    for(int op=0;op<2;op++){ // 枚举第一个位置按还是不按
        int res_t=0;
        memcpy(backup,g,sizeof g);
        if(op){ // 按
           g[0]=g[0]=='*'?'o':'*';  
           res_t++;
           for(int i=1;i<len;i++){
               if(g[i-1]!=dest[i-1]){
                   res_t++;
                   turn(i);
               }
            }
            if(g[len-1]==dest[len-1] && res_f > res_t)res_f=res_t;    
        }else{
            for(int i=1;i<len;i++){
               if(g[i-1]!=dest[i-1]){
                   res_t++;
                   turn(i);
               }
           }
           if(g[len-1]==dest[len-1] && res_f > res_t)res_f=res_t;   
        }
        memcpy(g,backup,sizeof g);
    }
    cout << res_f << endl;
    
    return 0;
}
posted @ 2020-11-22 12:43  RowryCho  阅读(135)  评论(0编辑  收藏  举报