• 蓝桥杯训练 | 递归与递推 | 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;
    }
    
  • 相关阅读:
    [Linux] VIM 常用快捷键2
    VIM 常用错误解决
    [ASM C/C++] C makefile:2: *** missing separator. Stop. 问题
    WIN 7 的vs2008 试用版评估期结束的解决方法
    未能写入输出文件“c:WindowsMicrosoft.NETFramework64v4.0.30319Temporary ASP.NET Files......”--“拒绝访问。 ”错误
    windows server 2012将计算机图标添加到桌面
    C# partial 说明
    处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”
    IIS7错误:不能在此路径中使用此配置节。如果在父级别上锁定了该节,便会出现这种情况。锁定是默认设置的(overrideModeDefault="Deny")......
    Win10离线安装.NET Framework 3.5的方法补充(附cab格式离线安装包下载)
  • 原文地址:https://www.cnblogs.com/Rowry/p/14018890.html
Copyright © 2020-2023  润新知