题目
皇后问题:输入整数N,要求N个国际象棋的皇后,摆在N*N的棋盘上,互相不能攻击,输出全部方案。
思路
输入一个正整数N,则程序输出N皇后问题的全部摆法。输出结果里的每一行2都代表一种摆法。行里的第i个数字如果是n,就代表第i行的皇后应该放在第n列。皇后的行、列编号都是从1开始运算。
代码编写
(1)main()函数
首先在所有函数外设置一个一个全局变量N,在定义一个用来存放皇后位置的数组,然后从最简单的主函数main说起,先输入几个皇后,从而确定好一个大概的表格框架,再调用nqueen()函数(注意:从第0行开始摆皇后,以确保每个位置都被尝试一遍)。
int N;
int queenpos[100];用来存放算好的皇后位置,最左上角是(0,0)
int main()
{
cin>>N;
nqueen(0);首先从第0行开始摆皇后
return 0;
}
(2)nqueen()函数
定义的nqueen函数是最该程序中最重要的一部分,首先是看定义的一个参数k是否与输入的皇后N相同,若相等,则说明N个皇后已经排好序了,则输出N个皇后的具体位置queenpos[i]+1(由于是从坐标(0,0)开始,所以输出的位置都要加1)," "负号内有一个空格,表示输出的结果之间有1个间距。
进入列循环,从i=0开始,进行执行,由于k开始也等于0,程序跳到if(k==j),从而确定好第一个皇后的位置(0,0)。再依次执行i=1,进行判断该皇后是否与前一个位置在同一行或者是在对角线上,显然在第二列的位置不能放皇后,然后再执行i=2,i=3可以放置皇后,但在当i=1时不能放置,说明该步骤是错误的,于是程序将重新开始从(1,0)开始放置,周而复始,便考虑到了所以的方案。
void nqueen(int k)
{
int i, j;
if (k == N)
{
for (i = 0; i < N; i++)
cout << queenpos[i] + 1 << " "; //输出排列好后N个皇后的位置
cout << endl;
return;
}
for (i = 0; i < N; i++) //进行列循环
{
for (j = 0; j < k; j++) //进行行循环
{
if (queenpos[j] == i || abs(queenpos[j]-i) == k - j) //判断后一个皇后是否与前一个皇后在同一列,或者是在对角线上
{
break;
}
}
if (k == j)
{
queenpos[k] = i;
nqueen(k + 1);
}
}
}
完整代码如下:
#include<iostream>
#include<cmath>
using namespace std;
int N; //定义N个皇后
int queenpos[100]; //存放皇后的位置
void nqueen(int k);
int main()
{
cin >> N;
nqueen(0); //从第0行开始摆皇后
return 0;
}
void nqueen(int k)
{
int i, j;
if (k == N) //N个皇后已经摆好
{
for (i = 0; i < N; i++)
cout << queenpos[i] + 1 << " "; //输出皇后的位置
cout << endl;
return;
}
for (i = 0; i < N; i++) //列循环
{
for (j = 0; j < k; j++) //行循环
{
if (queenpos[j] == i || abs(queenpos[j]-i) == k - j) //判断是否和摆好的皇后冲突
{
break;
}
}
if (k == j) //当前选的位置i不冲突
{
queenpos[k] = i; //将第k个皇后摆在位置i
nqueen(k + 1); //进行递归,摆下一个皇后
}
}
}
题目
逆波兰表达式:逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2+3的逆波兰表示法为+ 2 3。逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2+3) * 4的逆波兰表示法为* + 2 3 4。本题求解逆波兰表达式的值,其中运算符包括+ - * /四个
样例输入
* + 11.0 12.0 +24.0 35.0
样例输出
1357.000000
提示(11.0+12.0)*(24.0+35.0)
思路
首先了解逆波兰表达式定义:(1)1个数就是一个逆波兰表达式,值为该数。
(2)“运算符+空格+逆波兰表达式+空格+逆波兰表达式”是逆波兰表达式,值为俩逆波兰表达式运算结果。
采用递归的形式,先定义一个exp函数来读入并算出逆波兰表达式的值,让后读入数据s,利用switch语句进行运算,若首个读入的是运算符,则再调用exp()函数读入两个波兰表达式;若首次读入的是一个数,则输出该数。
提醒:atof()函数是字符串处理函数,功能是把字符串转换成浮点数。
完整代码如下:
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
double exp() //读入并算出逆波兰表达式的值
{
char s[20];
cin >> s;
switch (s[0]) {
case '+':return exp() + exp(); //若读入+号,则继续调用exp(),读入两个逆波兰表达式
case '-':return exp() - exp();
case '*':return exp() * exp();
case '/':return exp() / exp();
default:return atof(s); //将字符型转换成浮点型
break;
}
}
int main()
{
printf("%lf", exp());
return 0;
}
大数据201 田永兴