C语言练习题 ----递归

八皇后

会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。
对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2…b8,其中b为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。
给出一个数b,要求输出第b个串。串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小。

Input

第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数b(1 <= b <= 92)

Output

输出有n行,每行输出对应一个输入。输出应是一个正整数,是对应于b的皇后串。

Sample Input

2
1
92

Sample Output

15863724
84136275

Code

#include<stdio.h>
#include<math.h>
#include<string.h>
int queenPlace[92][8];
int count=0;int board[8][8];
void putQueen(int ithQueen);
int main()
{
	int n,i,j;
	for(i=0;i<8;i++)
	{
		for(j=0;j<8;j++)
			board[i][j]=-1;
		for(j=0;j<92;j++)
			queenPlace[j][i]=0;
	}
	putQueen(0);
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		int ith;
		scanf("%d",&ith);
		for(j=0;j<8;j++)
			printf("%d",queenPlace[ith-1][j]);
		printf("\n");
	}
	return 0;
}

void putQueen(int ithQueen)
{
	int i,k,r;
	if(ithQueen==8){
		count++;
		return;
	}
	for(i=0;i<8;i++){
		if(board[i][ithQueen]==-1){
			board[i][ithQueen]=ithQueen;
			for(k=count;k<92;k++)
				queenPlace[k][ithQueen]=i+1;
			for(k=0;k<8;k++)
				for(r=0;r<8;r++)
					if(board[k][r]==-1&&(k==i||r==ithQueen||abs(k-i)==abs(r-ithQueen)))
						board[k][r]=ithQueen;
			putQueen(ithQueen+1);
			for(k=0;k<8;k++)
				for(r=0;r<8;r++)
					if(board[k][r]==ithQueen)
						board[k][r]=-1;
		}
	}
}

逆波兰表达式

逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3。逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的逆波兰表示法为* + 2 3 4。本题求解逆波兰表达式的值,其中运算符包括+ - * /四个。

Input

输入为一行,其中运算符和运算数之间都用空格分隔,运算数是浮点数

Output

<输出为一行,表达式的值。
可直接用printf("%f\n", v)输出表达式的值v。

Sample Input

  * + 11.0 12.0 + 24.0 35.0

Sample Output

     1357.000000

Hint

可使用atof(str)把字符串转换为一个double类型的浮点数。atof定义在math.h中。此题可使用函数递归调用的方法求解。

#include<stdio.h>
#include<math.h>
#include <stdlib.h>
#include<string.h>
double exp(){
	char a[10];
	scanf("%s",a);
	switch(a[0]){
		case'+':return exp()+exp();
		case'-':return exp()-exp();
		case'*':return exp()*exp();
		case'/':return exp()/exp();
		default:return atof(a);
	}
}
int main()
{
	double ans;
	ans=exp();
	printf("%f",ans);
}

红与黑

有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻的黑色瓷砖移动。请写一个程序,计算你总共能够到达多少块黑色的瓷砖。

Input

包括多个数据集合。每个数据集合的第一行是两个整数W和H,分别表示x方向和y方向瓷砖的数量。W和H都不超过20。在接下来的H行中,每行包括W个字符。每个字符表示一块瓷砖的颜色,规则如下
1)‘.’:黑色的瓷砖;
2)‘#’:白色的瓷砖;
3)‘@’:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次。
当在一行中读入的是两个零时,表示输入结束。

Output

对每个数据集合,分别输出一行,显示你从初始位置出发能到达的瓷砖数(记数时包括初始位置的瓷砖)。

Sample Input

6 9
…#.
…#





#@…#
.#…#.
0 0

Sample Output

45

Code

#include<stdio.h>
int W,H;
char z[21][21];
int f(int x,int y){
	if(x<0||x>=W||y<0||y>=H)//如果走出矩阵范围
	return 0;
    if(z[x][y]=='#')
	return 0;
	else{
		z[x][y]='#';//将走过的瓷砖做标记			
	return 1+f(x-1,y)+f(x+1,y)+f(x,y-1)+f(x,y+1);
	}
}
int main()
{
	int i,j,num;
	while(scanf("%d%d",&H,&W)&&W!=0&&H!=0){
		num=0;
		for(i=0;i<W;i++)
			scanf("%s",z[i]);
		for(i=0;i<W;i++)
			for(j=0;j<H;j++)
				if(z[i][j]=='@')
					printf("%d\n",f(i,j));
	}
}

二叉树

在这里插入图片描述

如上图所示,由正整数1, 2, 3, …组成了一棵无限大的二叉树。从某一个结点到根结点(编号是1的结点)都有一条唯一的路径,比如从10到根结点的路径是(10, 5, 2, 1),从4到根结点的路径是(4, 2, 1),从根结点1到根结点的路径上只包含一个结点1,因此路径就是(1)。对于两个结点x和y,假设他们到根结点的路径分别是(x1, x2, … ,1)和(y1, y2, … ,1)(这里显然有x = x1,y = y1),那么必然存在两个正整数i和j,使得从xi 和 yj开始,有xi = yj , xi + 1 = yj + 1, xi + 2 = yj + 2,… 现在的问题就是,给定x和y,要求xi(也就是yj)。

Input

输入只有一行,包括两个正整数x和y,这两个正整数都不大于1000。

Output

输出只有一个正整数xi。

Sample Input

10 4

Sample Output

2

Code

//普通算法,没有用到递归
#include<stdio.h>
int main()
{
	int x,y;
	while(scanf("%d%d",&x,&y)!=EOF){
		while(x!=y){
			if(x>y)
				x=x/2;
			else if(x<y)
				y=y/2;
		}
		printf("%d",x);
	}
}

这个是递归

//递归算法
#include<stdio.h>
int common(int x,int y){
	if(x==y)
	return x;
	if(x>y)
		return common(x/2,y);
	return common(x,y/2);
}
int main()
{
	int m,n,result;
	scanf("%d%d",&m,&n);
	printf("%d\n",common(m,n));
}

放苹果

把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)注意:5,1,1和1,5,1是同一种分法

Input

第一行是测试数据的数目t(0<=t<=20)。以下每行均包含两个整数
M和N,以空格分开。1<=M,N<=10。

Output

对输入的每组数据M和N,用一行输出相应的K。

Sample Input

1
7 3

Sample Output

8

Code

#include<stdio.h>
int count(int x,int y){
	if(y==1||x==0)
		return 1;
	if(x<y)
	return count(x,x);
	return count(x,y-1)+count(x-y,y);
}
int main()
{
	int t,m,n;
	scanf("%d",&t);
	for(int i=0;i<t;i++){
		scanf("%d%d",&m,&n);
		printf("%d\n",count(m,n));
	} 
}
原创文章 27 获赞 26 访问量 7785

猜你喜欢

转载自blog.csdn.net/unseven/article/details/105224963