ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

递推与递归专题练习

2019-02-16 08:53:44  阅读:205  来源: 互联网

标签:ch 递归 read 递推 专题 rg define data getchar


CH0301 递归实现指数型枚举

搜索与回溯,指数级算法。

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;
    rg char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x){
    return x=read<T>();
}
typedef long long ll;
using namespace std;
vector<int>chosen;
int n;
void dfs(int x){
    if(x==n+1){
        for(unsigned i=0;i<chosen.size();++i)
            printf("%d ",chosen[i]);
        puts("");
        return;
    }
    dfs(x+1);
    chosen.push_back(x);
    dfs(x+1);
    chosen.pop_back();
}
int main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    read(n);
    dfs(1);
    return 0;
}

CH0302 递归/非递归实现组合型枚举

搜索与回溯。要字典序最小,所以优先往加入当前节点的分支搜索。

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;
    rg char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x){
    return x=read<T>();
}
typedef long long ll;
using namespace std;
vector<int> chosen;
unsigned n,m;
void dfs(unsigned x){
    if(chosen.size()>m||chosen.size()+(n-x+1)<m)
        return;
    if(x==n+1){
        for(unsigned i=0;i<chosen.size();++i)
            printf("%d ",chosen[i]);
        puts("");
        return;
    }
    chosen.push_back(x);
    dfs(x+1);
    chosen.pop_back();
    dfs(x+1);
}
int main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    read(n),read(m);
    dfs(1);
    return 0;
}

CH0303 递归实现排列型枚举

搜索与回溯

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;
    rg char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x){
    return x=read<T>();
}
typedef long long ll;
int n,order[11];
bool chosen[11];
void dfs(int x){
    if(x==n+1){
        for(int i=1;i<=n;++i)
            printf("%d ",order[i]);
        puts("");
        return;
    }
    for(int i=1;i<=n;++i)if(!chosen[i]){
        chosen[i]=1,order[x]=i;
        dfs(x+1);
        chosen[i]=0;
    }
}
int main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    read(n);
    dfs(1);
    return 0;
}

CH0201 费解的开关

描述

你玩过“拉灯”游戏吗?25盏灯排成一个5x5的方形。每一个灯都有一个开关,游戏者可以改变它的状态。每一步,游戏者可以改变某一个灯的状态。游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也要相应地改变其状态。

我们用数字“1”表示一盏开着的灯,用数字“0”表示关着的灯。下面这种状态

10111
01101
10111
10000
11011

在改变了最左上角的灯的状态后将变成:

01111
11101
10111
10000
11011

再改变它正中间的灯后状态将变成:

01111
11001
11001
10100
11011

给定一些游戏的初始状态,编写程序判断游戏者是否可能在6步以内使所有的灯都变亮。

做法

游戏有三个性质:

  1. 每个位置至多被点击一次。
  2. 若固定的第一行的点法,则满足题意的方案至多有一种。
  3. 点击的顺序不影响最终结果。

于是枚举第一行的点法,从第一行开始递推。

时间复杂度\(O(2^n n^2)\)。

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;
    rg char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x){
    return x=read<T>();
}
typedef long long ll;
co int N=10;
int g[N][N],n,ans,tmp[N][N];
void change(int x,int y){
    tmp[x][y]^=1;
    if(x-1) tmp[x-1][y]^=1;
    if(y-1) tmp[x][y-1]^=1;
    if(y+1<=n) tmp[x][y+1]^=1;
    if(x+1<=n) tmp[x+1][y]^=1;
}
int t;
char s[N];
int main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    read(t);
    n=5;
    while(t--){
        ans=25;
        for(int i=1;i<=n;++i){
            scanf("%s",s+1);
            for(int j=1;j<=n;++j)   
                g[i][j]=(s[j]-'0')^1;
        }
        for(int s=0;s<(1<<n);++s){
            for(int i=1;i<=n;++i)
                for(int j=1;j<=n;++j)
                    tmp[i][j]=g[i][j];
            bool ok=1;
            int tmp=s,k=1,cnt=0;
            while(tmp){
                if(tmp&1) change(1,k),++cnt;
                ++k,tmp>>=1;
            }
            for(int j=2;j<=n;++j)
                for(k=1;k<=n;++k)if(::tmp[j-1][k])
                    change(j,k),++cnt;
            for(int j=1;j<=n;++j) if(::tmp[n][j]){
                ok=0;
                break;
            }
            if(ok) ans=std::min(ans,cnt);
        }
        if(ans>6) puts("-1");
            else printf("%d\n",ans);
    }
    return 0;
}

标签:ch,递归,read,递推,专题,rg,define,data,getchar
来源: https://www.cnblogs.com/autoint/p/10386686.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有