1.十进制转二进制
2.斐波那契数列
3.翻牌问题
4.打靶问题
5.八皇后问题
#include "stdio.h"
#include<time.h>
#include<iostream>
#include<cstdio>
#include<cstring>
#include "stdlib.h"
//1.输入一个自然数(<90000), 分别用递归法和非递归法求其二进制表示.
//算法设计思想:num/2就是num的二进制序列当中除去最低位之外的部分,num%d表示输出num的二进制序列当中的最低位
/*递归算法*/
void fun(int num)
{
if(num==0)
return ;
else{
fun(num/2);
printf("%d", num%2);
}
}
int main()
{
int num;
printf("请输入一个自然数:");
scanf("%d",&num);
while(0>num||num>=90000) {
printf("请重新输入:");
scanf("%d", &num);
}
fun(num);
return 0;
}
/*非递归算法*/
int main()
{
int num;
int i=0,j,b[32];
printf("请输入一个自然数:");
scanf("%d",&num);
while(num<0||num>=90000)
{
printf("请重新输入:");
scanf("%d",&num);
}
while(num!=0)
{
b[i++]=num%2;
num=num/2;
}
for(j=i-1;j>=0;j--)
printf("%d",b[j]);
}
//2.分别用递归法和非递归法求Fibonacci数列的前1000位,并比较计算时间的差异.
//函数FiboD(num)的特点是,如果n不是递归出口,那么一个规模是n的Fbio函数就可以转化为两个规模更小的Fbio函数的和,一个是Fbio(n-1),一个是Fbio(n-2)。如果这两个函数仍然没有到达递归终点,仍需要继续递归分解。
/*递归算法*/
int FiboD(int n)
{
int val;
if(n==1||n==2)
return 1;
val = FiboD(n-1)+FiboD(n-2);
return val;
}
/*非递归算法*/
int FiboF(int n){
int a = 1, b = 1;
if(n==1 || n==2) return 1;
for(int i=3; i<=n; i++){
int tmp = b;
b = a + b;
a = tmp;
}
return b;
}
int main()
{
int num=50;
/* FbioD递归持续的时间*/
clock_t start1, finish1;
double duration1;
printf("FiboD递归的时间是:");
start1 = clock();
FiboD(num);
finish1 = clock();
duration1 = (double)(finish1 - start1) / CLOCKS_PER_SEC;
printf( "%f seconds\n", duration1 );
/* FiboD非递归测持续的时间*/
clock_t start2, finish2;
double duration2;
printf("FiboF非递归的时间是:");
start2 = clock();
FiboF(num);
finish2 = clock();
duration2 = (double)(finish2 - start2) / CLOCKS_PER_SEC;
printf( "%f seconds\n", duration2 );
system("pause");
}
/*3.用递归算法完成如下问题:有52张牌,使它们全部正面朝上,第一轮是从第2张开始,凡是2的倍数位置上的牌翻成正面朝下;
/*第二轮从第3张牌开始,凡是3的倍数位置上的牌,正面朝上的翻成正面朝下,正面朝下的翻成正面朝上;第三轮从第4张牌开始,凡是4的
倍数位置上的牌按上面相同规则翻转,以此类推,直到第一张要翻的牌超过52为止。统计最后有几张牌正面朝上,以及它们的位置号.*/
using namespace std;
bool card[100];
void turn(int x)
{
if(x>52) return;
for(int i=x;i<=52;i+=x)
{
card[i]=!card[i];
}
turn(x+1);
}
int main()
{
memset(card,1,sizeof(card));
turn(2);
for(int i=1;i<=52;i++)
{
if(card[i])
cout<<i<<endl;
}
return 0;
}
/*4.一个射击运动员打靶,靶一共有10环,连开6枪打中45环的可能性有多少种? (每一枪最少是0环,最多是10环)*/
using namespace std;
int sum;
int store[6];
void compute(int score,int num)
{
//score<0即总的成绩超过45环,或者剩下要打的靶的成绩大于10环乘以剩下要打的靶数
//这两种情况下不用在大了
if(score<0||score>(num+1)*10)
return;
//如果满足条件并且打到最后一次
if(num==0)
{
store[num]=score;
sum++;
return;
}
for(int i=0;i<=10;++i)
{
//顺序倒了,store[6]是第一次打的,。。。store[0]是最后一次打的
store[num]=i;
compute(score-i,num-1);
}
}
int main()
{
compute(45,5);
cout<<"总数"<<sum<<endl;
return 0;
}
//5.在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,输出所有摆法。
//编程思想:有8个元素的数组记录已经摆放的棋子摆在什么位置,当要放置一个新的棋子时,只需要判断它与已经放置的棋子之间是否冲突就行了。
/*从棋盘的第一行开始,从第一个位置开始,依次判断当前位置是否能够放置皇后,判断的依据为:同该行之前的所有行中皇后的所在位置进行比较,如果在同一列,或者在同一条斜线上(斜线有两条,为正方形的两个对角线),都不符合要求,继续检验后序的位置。
如果该行所有位置都不符合要求,则回溯到前一行,改变皇后的位置,继续试探。
如果试探到最后一行,所有皇后摆放完毕,则直接打印出 8*8 的棋盘。最后一定要记得将棋盘恢复原样,避免影响下一次摆放。*/
int Queenes[8]={0},Counts=0;
int Check(int line,int list){
//遍历该行之前的所有行
for (int index=0; index<line; index++) {
//挨个取出前面行中皇后所在位置的列坐标
int data=Queenes[index];
//如果在同一列,该位置不能放
if (list==data) {
return 0;
}
//如果当前位置的斜上方有皇后,在一条斜线上,也不行
if ((index+data)==(line+list)) {
return 0;
}
//如果当前位置的斜下方有皇后,在一条斜线上,也不行
if ((index-data)==(line-list)) {
return 0;
}
}
//如果以上情况都不是,当前位置就可以放皇后
return 1;
}
//输出语句
void print()
{
for (int line = 0; line < 8; line++)
{
int list;
for (list = 0; list < Queenes[line]; list++)
printf("0");
printf("*");
for (list = Queenes[line] + 1; list < 8; list++){
printf("0");
}
printf("\n");
}
printf("================\n");
}
void eight_queen(int line){
//在数组中为0-7列
for (int list=0; list<8; list++) {
//对于固定的行列,检查是否和之前的皇后位置冲突
if (Check(line, list)) {
//不冲突,以行为下标的数组位置记录列数
Queenes[line]=list;
//如果最后一样也不冲突,证明为一个正确的摆法
if (line==7) {
//统计摆法的Counts加1
Counts++;
//输出这个摆法
print();
//每次成功,都要将数组重归为0
Queenes[line]=0;
return;
}
//继续判断下一样皇后的摆法,递归
eight_queen(line+1);
//不管成功失败,该位置都要重新归0,以便重复使用。
Queenes[line]=0;
}
}
}
int main() {
//调用回溯函数,参数0表示从棋盘的第一行开始判断
eight_queen(0);
printf("摆放的方式有%d种",Counts);
return 0;
}