递归与递推

求解递推问题:

1)把大问题细分成子问题,子问题的求解逻辑跟大问题是一样的;(递推式)(起始条件) 2)终止条件:就是细分到最小的那个最小的条件 递推加法原理: 如果有一件事有n类方法,第一类有a1种方法,第二类有a2种方法,……第n类有an种方法,则这件事的方法总数为:a1+a2……+an

P1255 数楼梯

alt 问题理解: 1)递推式,f(n)走到n,要么是走一步(f(n-1))要么是走两步(f(n-2)) 2)终止条件:细分的最小条件;f(1)=1,f(2)=1 3)斐波那契数列,这道题1,1,2,3,5…… 4)求第n项是多少,f(0)=1,f(1)=1,f(n)=?; 代码:

#include<cstdio>//调用 scanf和printf 库
#include<cstring>//调用 memset 库
int n,ns=1; 
int a[5010],b[5010],c[5010];
//定义
//注意数组大小
void Fibonacci()
//开始
{
    a[1]=1,b[1]=2;//注意初始化
    for(int i=3;i<=n;i++)//从第3个循环
    {
        for(int j=1;j<=ns;j++)c[j]=a[j]+b[j];//相加
        for(int j=1;j<=ns;j++)//进位
        {
            if(c[j]>9)//大于9才进
            {
                c[j+1]+=c[j]/10;
                c[j]%=10;
                if(j+1>ns)ns++;//小心要多留一位
            }
        }
        for(int j=1;j<=ns;j++)a[j]=b[j];
        for(int j=1;j<=ns;j++)b[j]=c[j];
        //交换
    }
}
int main()
{
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    memset(c,0,sizeof(c));
    //清 0       优化
    scanf("%d",&n);//输入
    if(n<3)//小于 3 要多加小心----------卡了我两次
    {
        printf("%d",n);
        return 0;
    }
    Fibonacci();
    //高精和递推合并
    for(int i=ns;i>0;i--)printf("%d",b[i]);
    //逆序输出
    return 0;//再见
}

P1002 [NOIP2002 普及组] 过河卒

alt alt

#include<iostream>
using namespace std;
const int N=30;
//vis[i][j]如果是true代表点(i,j)的 控制点,flase则代表不是 
bool vis[N][N];//全局数组,默认代表初始化为flase
long long  a[N][N];//a[i][j]:zu 从点(0,0)到点(i,j)的方案数
int dx[9]={0,2,1,-1,-2,-2,-1,1,2};
int dy[9]={0,1,2,2,1,-1,-2,-2,-1};
int main(){
//	一行四个正整数,分别表示 B 点坐标和马的坐标。
	int n,m;//B点坐标,终点
	int x,y;//吗的坐标 
	cin>>n>>m>>x>>y;
	//设置吗控制的点为不能走的点
//	vis[x][y]=true;
//	vis[x+2][y+1]=true;
//	vis[x+1][y+2]=true;
//	vis[x-1][y+2]=true;
//	vis[x-2][y+1]=true;
//	vis[x-2][y-1]=true;
//	vis[x-1][y-2]=true;
//	vis[x+1][y-2]=true;
//	vis[x+2][y-1]=true;
//     
for(int i=0;i<9;i++)
{
	int nx=x+dx[i];
	int ny=y+dy[i];
	vis[nx][ny]=true; 
}
    //初始条件
	//第0行(列:0-m)
	for(int j=0;j<=m;j++){
//		if(vis[0][j]==false)
        if(!vis[0][j]) a[0][j]=1;//不是马的控制点,方案数为1
		else break;//ma 的控制点(控制点同行的点都走不了),退出 
	} 
	//第0列(行:0-n)
	for(int i=0;i<=n;i++)
	{ 
		if(!vis[i][0])a[i][0]=1;//不是马的控制点,方案数为1
		else break;//ma 的控制点(控制点同列的点都走不了),退出 
	 } 
	 for(int i=1;i<=n;i++)
	 {
	 	for(int j=1;j<=m;j++)
	 	{  //加法原理 
	 		if(!vis[i][j])a[i][j]=a[i-1][j]+a[i][j-1];
		 }
	  } 
	cout<<a[n][m]<<endl; 
	return 0;
} 

3用上二维数组

#include<iostream>
using namespace std;
const int N=30;
//vis[i][j]如果是true代表点(i,j)的 控制点,flase则代表不是 
bool vis[N][N];//全局数组,默认代表初始化为flase
long long  a[N][N];//a[i][j]:zu 从点(0,0)到点(i,j)的方案数
//int dx[9]={0,2,1,-1,-2,-2,-1,1,2};
//int dy[9]={0,1,2,2,1,-1,-2,-2,-1};

int dir[9][2]={{0,0},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}} ;

int main(){
//	一行四个正整数,分别表示 B 点坐标和马的坐标。
	int n,m;//B点坐标,终点
	int x,y;//吗的坐标 
	cin>>n>>m>>x>>y;
	//1.设置吗控制的点为不能走的点
//	vis[x][y]=true;
//	vis[x+2][y+1]=true;
//	vis[x+1][y+2]=true;
//	vis[x-1][y+2]=true;
//	vis[x-2][y+1]=true;
//	vis[x-2][y-1]=true;
//	vis[x-1][y-2]=true;
//	vis[x+1][y-2]=true;
//	vis[x+2][y-1]=true;
//  2.   
//for(int i=0;i<9;i++)
//{
//	int nx=x+dx[i];
//	int ny=y+dy[i];
//	vis[nx][ny]=true; 
//}
//3.二维数组方法 
for(int i=0;i<9;i++)
{
	int nx=x+dir[i][0];
	int ny=y+dir[i][1];
	if(nx>=0&&ny>=0)vis[nx][ny]=true; 
}
    //初始条件
	//第0行(列:0-m)
	for(int j=0;j<=m;j++){
//		if(vis[0][j]==false)
        if(!vis[0][j]) a[0][j]=1;//不是马的控制点,方案数为1
		else break;//ma 的控制点(控制点同行的点都走不了),退出 
	} 
	//第0列(行:0-n)
	for(int i=0;i<=n;i++)
	{ 
		if(!vis[i][0])a[i][0]=1;//不是马的控制点,方案数为1
		else break;//ma 的控制点(控制点同列的点都走不了),退出 
	 } 
	 for(int i=1;i<=n;i++)
	 {
	 	for(int j=1;j<=m;j++)
	 	{  //加法原理 
	 		if(!vis[i][j])a[i][j]=a[i-1][j]+a[i][j-1];
		 }
	  } 
	cout<<a[n][m]<<endl; 
	return 0;
} 

代码2:

#include<bits/stdc++.h>
using namespace std;
int n,a[5005]={1},b[5005]={1},c[5005]={1},len=1;
//高精度加法
void f(){
	int jw=0;//进位 
	for(int i=0;i<len;i++)
	{
		c[i]=a[i]+b[i]+jw;
		jw=c[i]/10;
		c[i]=c[i]%10; 
	}
	if(jw!=0){
		c[len]=jw;
		len++;
	}
	for(int i=0;i<len;i++){
		a[i]=b[i];
		b[i]=c[i];
	}
} 
int main(){
	
	cin>>n;
	for(int i=2;i<=n;i++){
		f();//调用高精度加法 
	}
	for(int i=len-1;i>=0;i--){
		cout<<c[i];//输出值
	}
	return 0;
}

P1044 [NOIP2003 普及组] 栈

alt alt alt 解析: 这道题可以理解成,有i个要进栈的数在排队,栈内有j个数,还有等出栈的数 1.有两种操作方式,pop,push,两种操作数要加起来,f(i,j)表示的是该时刻的情况数 2.有两个数,第一个数i表示是未进栈的数,第二个数j表示栈内的数。 3.栈内的数j如果大于0,就有两种操作方法要么进栈要么出栈f[i][j]=f[i][j-1]+f[i-1][j+1],表示的意思是pop时因为不涉及进栈的数所以i不涉及,栈内的数减一,加上,push,未进栈的数减一,栈内的数加1,。 4.j=0;表示栈内没有数了,只能进行进栈操作f[i] [j]=f[i-1][j+1];

#include<bits/stdc++.h>
using namespace std;
int f[20][20],n;
int main(){
	
	cin>>n;
	//第一个数i,表示的是未进栈
//	第二个事数j,表示栈内的数
    for(int j=0;j<20;j++){
    	f[0][j]=1;//因为最后都会分成f[0][j]=1,1种情况的时候
	} 
	for(int i=1;i<20;i++)
{
	for(int j=0;j<20;j++){
		if(j==0)f[i][j]=f[i-1][j+1];
		else{
			f[i][j]=f[i][j-1]+f[i-1][j+1];
		}
	}
	}
	cout<<f[n][0];//n个数没有进栈,栈内有0个数的情况。
		return 0;
} 

P1028 [NOIP2001 普及组] 数的计算

alt alt 思路:f[i]表示i处理后具有该性质数的个数 已知当i=1时,f[i]=1; i>=2,f[i]=f[1]+f[2]+……+f[i/2]

#include<iostream>
using namespace std;
const int N=1e3+10;
int f[N];//f[i]:i处理后具有该性质的个数 

int main(){
	int n;
	cin>>n;
	f[1]=1;
	for(int i=1;i<=n;i++)
	{
		f[i]=1;//i自己
		for(int j=1;j<=i/2;j++)
		{
			f[i]+=f[j];
		 } 
	 } 
	 cout<<f[n];
     	
	return 0;

} 

P1464 Function

alt shuru

1 1 1
2 2 2
-1 -1 -1

输出

w(1, 1, 1) = 2
w(2, 2, 2) = 4

alt 超时代码

#include<bits/stdc++.h>
using namespace std;
long long dfs(long long a,long long b,long long c)
{   if(a<=0||b<=0||c<=0)return 1;
    if(a>20||b>20||c>20)return dfs(20,20,20);
	if(a<b&&b<c)return  dfs(a,b,c-1)+dfs(a,b-1,c-1)-dfs(a,b-1,c);
	return dfs(a-1,b,c)+dfs(a-1,b-1,c)+dfs(a-1,b,c-1)-dfs(a-1,b-1,c-1);
}
void lesson1()
{
	long long a,b,c;
	while(cin>>a>>b>>c){//只要一直有就一直输入知道-1,-1,-1
	   if(a==-1&&b==-1&&c==-1)break;
	   printf("w(%lld, %lld, %lld) = %lld\n ",a,b,c,dfs(a,b,c)) ;
		
	}
 } 
 
 int main(){
 	
 	lesson1();
 	return 0;
 }

优化后的正确答案:

#include<bits/stdc++.h>
using namespace std;
long long dp[22][22][22];
long long dfs(long long a,long long b,long long c)
{   if(a<=0||b<=0||c<=0)return 1;
    if(a>20||b>20||c>20)a=b=c=20;//因为当abc大于20时都当成20使用所以不需要多次调用直接赋值 
    if(dp[a][b][c])return dp[a][b][c];//如果dp有值就直接反回值 
	if(a<b&&b<c)return  dp[a][b][c]=dfs(a,b,c-1)+dfs(a,b-1,c-1)-dfs(a,b-1,c);/*dp没有值才进行计算
	然后赋值个dp,然后返回*/ 
	return dp[a][b][c]= dfs(a-1,b,c)+dfs(a-1,b-1,c)+dfs(a-1,b,c-1)-dfs(a-1,b-1,c-1);
}
void lesson1()
{
	long long a,b,c;
	while(cin>>a>>b>>c){//只要一直有就一直输入直到-1,-1,-1
	   if(a==-1&&b==-1&&c==-1)break;
	   printf("w(%lld, %lld, %lld) = %lld\n" ,a,b,c,dfs(a,b,c)) ;
		
	}
 } 
 
 int main(){
 	
 	lesson1();
 	return 0;
 }

P1928 外星密码

alt 输入:

AC[3FUN]

输出:

ACFUNFUNFUN

理解题目: 可以看成一个字符串由多个字符串拼接成 S:AC(s1)DXabc(s3) (起始条件)f(s)=f(s1+s2+s3)=f(s1)+f(s2)+f(s3)//f(s2):表示D个f(x)拼接成 如果Si没有"[""]"f(Si)=si//没有加密的解密还是他本身,(终止条件)

#include<bits/stdc++.h>
using namespace std;
string f(string s)
{  string ans; 
	//对s中的每个字符进行遍历
	for(int i=0;i<s.length();i++)
	{//如果找到的字符未加密,则添加到ans中
		if(s[i]!='['){
			ans+=s[i];
			continue;
		}
		//如果找到的字符串加密了,抽D和x(x的位置是j-mark的长度)
		int mark=i+1,d=0,right=1;//mark会作为指针去寻找,right表示的中括号的个数 
		while(s[mark]>='0'&&s[mark]<='9'){//a[mark]如果是大于字符的'0',小于字符的'9',字符串变数字
		    d=d*10+s[mark]-'0';//就是找到D,a[mark]-'0':就是把字符串转换成数字
			mark++;//一直找数字 
		} 
		
		for(int j=i+1; ;j++)
		{//找中括号的个数,如果[,等于]的个数那么就代表找完压缩的数据了 
			if(s[j]=='[')right++;
			if(s[j]==']')right--;
			if(right==0){
				string x=s.substr(mark,j-mark);
				x=f(x);
				//将D个X添加到ans中
				for(int k=1;k<=d;k++)ans+=x;//把很多个x拼接到ans上 	 
				i=j;
			    break;
			} 
		
		 } 
		 //重复上面过程,返回ans的值
		 
	 } 
	
	 
	 return ans;
	 
	  
}

int main(){
	string s;
	cin>>s;
	cout<<f(s);
	
	return 0;
}

P2437 蜜蜂路线

alt 题目理解: 分解题目可以理解成;走到k的路径等于走到比他小的两个数字路径的和; f(k)=f(k-1)+f(k-2){斐波那契数列} 从2——》5等于从1——》4 即从m--->n抽象成从1——》(n-m+1)

数学化抽象:f(n-m+1)

要用到高精度加法,和爬楼梯那题类似 代码

#include<bits/stdc++.h>
using namespace std;
int n,m,a[5005]={1},b[5005]={1},c[5005]={1},len=1;
void f(){
	int jw=0;
	for(int i=0;i<len;i++)
	{
		c[i]=a[i]+b[i]+jw;
		jw=c[i]/10;
		c[i]=c[i]%10;
	}
	if(jw!=0){
		c[len]=jw;//进位 
		len++;
	}
	for(int i=0;i<len;i++){
	    a[i]=b[i];
	    b[i]=c[i];
	}

	
}
int main(){
	
	cin>>m>>n;
	for(int i=3;i<=n-m+1;i++){f();}
    for(int i=len-1;i>=0;i--){
    	cout<<c[i];
	}
	
	return 0;
}

P1164 小A点菜

alt 输入:

4 4
1 1 2 2

输出:

3

90分代码有超时(dfs):

#include<bits/stdc++.h>
using namespace std;
int n,m,a[105],mark[105]={0},ans=0;
void dfs(int step,int flag){//step步长,flag标记 
	if(step>m)return;//边界条件 
	if(step==m){//终止条件 
		ans++;
		return;
	}
	for(int i=flag;i<n;i++){
		if(mark[i]==0){
			mark[i]=1;
			dfs(step+a[i],i);
			mark[i]=0;
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=0;i<n;i++)cin>>a[i];
	dfs(0,0);
	cout<<ans; 
	return 0;
} 

代码(dfs);

#include<bits/stdc++.h>
using namespace std;
int n,m,a[105],dp[101][10001];//dp记忆化 
int dfs(int pos,int s){
   int ans=0;
   if(s==m)return 1;
   else if(s>m)return 0;
   if(dp[pos][s])return dp[pos][s];
   for(int i=pos;i<n;i++)
     	ans+=dfs(i+1,s+a[i]);
    return dp[pos][s]=ans;
   
}

void lesson1(){
	cin>>n>>m;
	for(int i=0;i<n;i++)cin>>a[i];
	cout<<dfs(0,0);
} 
int main(){
	lesson1();
	return 0;
}

用背包动态规划:

P1990 覆盖墙壁

alt alt alt alt

#include<bits/stdc++.h>
using namespace std;
int n,f[1000005]={0,1,2},k[1000005]={0,0,1};
int main(){
	
	cin>>n;
	for(int i=3;i<=n;i++){
		f[i]=(f[i-1]+f[i-2]+k[i-1]*2)%10000;
		k[i]=(f[i-2]+k[i-1])%10000;
		
	}
	cout<<f[n];
	return 0;
}

P3612 [USACO17JAN] Secret Cow Code S

alt 题目的理解:就是先个定一个字符串(COW),然后扩展,先把给定的字符串最后一位的字符(W)放到要开始复制的首位然后顺序复制(WCO) 如果还没到规定的位置则再进行扩展(double翻倍)得到的长度都比原来的翻一倍 alt alt alt 思路:找到能覆盖m的最小拓展数

#include<bits/stdc++.h>
using namespace std;
//找到能覆盖N的最小拓展
//将拓展进行压缩/
//压缩思路:需要将N压缩到当前拓展的前半部分
//循环上面三部操作
//知道N在初始字符串长度中,输出结果 

int main(){
	string s;
	long long len1,len2,n,k;//len1 :s的长度,len2最长映射长度,要多长才能包裹n
	cin>>s>>n;
	len1=s.length();
	len2=len1;
	while(len2<n)len2*=2;//找到能包裹住n的最小拓展
	while(n>len1){//当n大于len1时就压缩 
	     k=len2/2+1; 
		if(n>=k){//如果n的位置在拓展的右边(len2/2的右边)就要做映射,映射到拓展的左边 
		   if(n==k)n--;
		   else n=n-k;
	} 
	len2/=2;//拓展后的压缩,没用的进行压缩掉 
  }
  cout<<s[n-1]<<endl;//因为s数组是从0开始的,n的计数是从1开始的所一要对齐 
	return 0;
}

P1259 黑白棋子的移动

alt 输入

7

输出

ooooooo*******--
oooooo--******o*
oooooo******--o*
ooooo--*****o*o*
ooooo*****--o*o*
oooo--****o*o*o*
oooo****--o*o*o*
ooo--***o*o*o*o*
ooo*o**--*o*o*o*
o--*o**oo*o*o*o*
o*o*o*--o*o*o*o*
--o*o*o*o*o*o*o*

alt

#include<bits/stdc++.h>
using namespace std;
int n;
char a[205];
string b[4]={"ooo*o**--","o--*o**oo","o*o*o*--o","--o*o*o*o"};//特判
//输出函数
void shuchu(int l,int r){
	for(int i=l;i<=r;i++)cout<<a[i];
	cout<<endl;
} 
void f(int step){
	
	if(step==3){
		for(int i=0;i<4;i++)
		{
			cout<<b[i];
			shuchu(10,2*n+2);//从第10位开始到2*n+2位都进行输出
		}
		return;
	}
	shuchu(1,2*n+2);//先进行一波无脑输出 ,步长为3的时候就直接输出上面的条件里面的代码 
	swap(a[step],a[step*2+1]);
	swap(a[step+1],a[step*2+2]);
	shuchu(1,2*n+2);
	swap(a[step],a[step*2-1]);
	swap(a[step+1],a[step*2]);
	f(step-1);//不停的往后递推 
	
} 
int main(){

	cin>>n;
	for(int i=1;i<=n;i++){//初始化 
		a[i]='o';
		a[i+n]='*';
	}
	a[2*n+1]='-';//初始化 
	a[2*n+2]='-';//初始化 
	f(n);//递推函数 
	
	return 0;
} 

P1010 [NOIP1998 普及组] 幂次方

alt 题目理解: 所有的数字都用2,来表示 1.对于一个数字n,拆成多个2的幂次方的和 2.将其表示为形如n=2(k1)+2(k2)+……+2(kk) 3.对于任意的一个ki,递归的调用1-3步 直到能用2,0,+,(),表示所有的内容为止

#include<bits/stdc++.h>
using namespace std;
int mark[20]={1};
void f(int n){//拆分 
	 int flag=0;
	 while(n>=mark[flag]){
	 	flag++;
	 } 
	 flag--;
	 if(flag==1){
	 	cout<<2;
	 }else{
	 	if(flag==0){
	 		cout<<"2(0)";
		 }else{
		 	cout<<"2(";
		 	f(flag);
		 	cout<<")";
		 }
	 }
	 n-=mark[flag];
	 if(n!=0){
	 	cout<<"+";
	 	f(n);
	 }
}
int main(){
	
	int n;
	cin>>n;
	for(int i=1;i<17;i++)mark[i]=mark[i-1]*2;
	f(n);
	return 0;
} 

P1228 地毯填补问题

alt 输入:

3                          
3 3   

输出

5 5 1
2 2 4
1 1 4
1 4 3
4 1 2
4 4 1
2 7 3
1 5 4
1 8 3
3 6 3
4 8 1
7 2 2
5 1 4
6 3 2
8 1 2
8 4 1
7 7 1
6 6 1
5 8 3
8 5 2
8 8 1

alt 理解题目: 就是把大的正方形分成小的正方形88——>四个44的方格——>16个2*2的方格 alt 思路: 1。将一个2的k次方的方块分成4个k-1次方的方块 2.定位障碍物的位置,在四大块的哪一块 3.在包含障碍物的方块的对应角上加一个地毯(三个障碍物) 4.对于四个小块,递归的调用1-4步求解 5.当我们的方块为1的时候 6就是要列出四种情况 alt 代码答案是错的但是思路是正确的:

#include<bits/stdc++.h>
using namespace std;
void f(int x,int y,int gx,int gy,int l){
	if(l==1)return ;//终止条件
	//先确定障碍物在那个区块
	//在这个区块对应角放上一个地毯
	//再将原来的大快的区块分成4个小弟区块递归即可
	if(gx<=x+l/2-1&&gy<=y+l/2-1){//判断公主在左上角的区块 
		cout<<x+l/2<<" "<<y+l/2<<" "<<1<<endl;//在这个区块对应角放上一个地毯
		f(x,y,gx,gy,l/2);//把一个长度为l的问题拆分成l/2的问题 
		f(x,y+1/2,x+l/2-1,y+l/2,l/2);
		f(x+l/2,y,x+l/2,y+l/2-1,l/2);
		f(x+l/2,y+l/2,x+l/2,y+l/2,l/2);
	} else if(gx<=x+l/2-1 &&gy>=y+l/2){//障碍物在右上角 
		cout<<x+l/2<<" "<<y+l/2-1<<" "<<2<<endl;//在这个区块对应角放上一个地毯
		f(x,y,x+l/2-1,y+l/2-1,l/2);//把一个长度为l的问题拆分成l/2的问题 
		f(x,y+l/2,gx,gy,l/2);
		f(x+l/2,y,x+l/2,y+l/2-1,l/2);
		f(x+l/2,y+l/2,x+l/2,y+l/2,l/2);	
	}else if(gx>=x+l/2 &&gy<=y+l/2-1){//障碍物在左下角 
		cout<<x+l/2-1<<" "<<y+l/2<<" "<<3<<endl;//在这个区块对应角放上一个地毯
		f(x,y,x+l/2-1,y+l/2-1,l/2);//把一个长度为l的问题拆分成l/2的问题 
		f(x,y+l/2,x+l/2-1,y+l/2,l/2);
		f(x+l/2,y,gx,gy,l/2);
		f(x+l/2,y+l/2,x+l/2,y+l/2,l/2);	
	}else if(gx>=x+l/2 &&gy>=y+l/2){//障碍物在右下角 
		cout<<x+l/2-1<<" "<<y+l/2-1<<" "<<4<<endl;//在这个区块对应角放上一个地毯
		f(x,y,x+l/2-1,y+l/2-1,l/2);//把一个长度为l的问题拆分成l/2的问题 
		f(x,y+l/2,x+l/2-1,y+l/2,l/2);
		f(x+l/2,y,x+l/2,y+l/2-1,l/2);
		f(x+l/2,y+l/2,gx,gy,l/2);
	}
}
int main(){
	int k,x,y;
	cin>>k>>x>>y;
	f(1,1,x,y,pow(2,k));//1,1是做上角的坐标,长度是2的k吃方 ,x,y是公主(障碍物体)
	 
	return 0;
}

P1498 南蛮图腾

alt alt alt alt 代码

#include<bits/stdc++.h>
using namespace std;
char c[2050][2050];//矩阵的大小 
void f(int x,int y,int n){
    if (n==1){
    	c[x][y+1]='/';
    	c[x+1][y]='/';
    	c[x][y+2]='\\';
    	c[x+1][y+3]='\\';
    	c[x+1][y+1]='_';
    	c[x+1][y+2]='_';
    	return;
	}
	int distance=pow(2,n);//pow(2,n)=2^n
	f(x,y+distance/2,n-1);//一号三角形
	f(x+distance/2,y,n-1);//二号三角形
	f(x+distance/2,y+distance,n-1); //三号三角形
}
int main(){
	int n;
	cin>>n;
	memset(c,' ',sizeof(c));//把所有的地方都设置成空格
	f(0,0,n);
	int distance=pow(2,n); 
	for(int i=0;i<distance;i++)//行 
	{
		for(int j=0;j<distance*2;j++)//列 
		{
			cout<<c[i][j];
		}
		cout<<endl;
	}
	return 0;
} 
全部评论

相关推荐

想去夏威夷的小哥哥在度假:5和6才是重点
点赞 评论 收藏
分享
掩卷思:这简历做的感觉好简陋啊,找个模板呗
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务