会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将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
#include
#include
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
#include
#include
#include
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
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
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
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
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));
}
}