算法 < 二 > —— 枚举、递归

枚举运用的地方:
1,基于逐个尝试答案的一种问题解决策略
2,找不到数学公式

eg:求小于N的最大素数,找不到数学公式,根据n进行计算素数。

枚举

完美立方

题目:

在这里插入图片描述
输出样例:
``

思路:
1,需要把所有的数字进行尝试一边
2,确定范围
3,for循环遍历

//1,进行一个一个尝试的去试
//2,把一些不会是答案的进行排除。——确定范围 
// b<=c<=d 都小于N=100
//a [2,N] b[2,a-1] c[b,a-1] d[c,a-1]
 
#include <iostream>
#include <cstdio>
using namespace std;
int main( ){
    int n;
	scanf("%d",&n);//输出一个n
	int a , b ,  c , d;
	for(int a = 2;a <= n ; a++)
	for(int b = 2;b <= a-1 ; b++)
	for(int c = b;c <= a-1;c++)
	for(int d = c;d <= a-1;d++)
		if(a*a*a == b*b*b + c*c*c + d*d*d)
			printf("Cube = %d,Triple =(%d,%d,%d)\n",a,b,c,d);
	        return 0;
}
	

生理周期

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路:
1,从d+1天一直试到20252天 所以使用枚举 设相距k天
2,(k - p) % 23 == 0 && (k - e) % 28 == 0 && (k - i)%33 == 0

//1,输入p,e,i,d 情感 智力 体力 d为距离下一次出现在同一天的日子,要求输入的日子都小于365总日子小于21252
//2,输出下一次相距的日子 
//思路:从d+1天一直试到20252天 所以使用枚举 设相距k天 
///(k - p) % 23 == 0 && (k - e) % 28 == 0 && (k - i)%33 == 0 
#include <iostream>
#include <cstdio>
using namespace std;
#define N 21252;
int main( ){
    int p,e,i,d,casenum = 0;
    while(cin >> p >> e >> i >> d && p!= -1){
    	++casenum;
    	int k;
    	for(k = d + 1;(k-p)%23;++k);
    	for(;(k-e)%28;k+=23);
    	for(;(k-i)%33;k+=23*28);	 
    	cout << "Case:"<<casenum<< "the next triple peak occurs in "<< k - d<<"days";
    	
	}
	
	return 0;
}
      

称硬币

题目:

在这里插入图片描述
输入与输出
在这里插入图片描述

代码:

//思路:先假设一个硬币是轻的,看符合不符合结果,不符合在假设它是不是重的,看符合不符合称量结果,把所有的硬币都试一遍

#include <iostream>
#include <cstring>
//ABCD EFGH even
using namespace std;
char Left[3] [7];//12/2=6最多放6个
char Right [3] [7];
char result [3] [7];//存在三组数据而且每组数据最多只能有6个字母
bool isFake(char c,bool light){//c表示为假币 light为轻的
for(int i = 0;i < 3; i++){
    char * pLeft,* pRight;//指向天平两边的字符串
    if(light){//假币轻的话
          pLeft = Left[i];
          pRight = Right[i];
    }
    else{//假币重的话,进行左右对换
        pLeft = Right[i];
        pRight = Left[i];
    }
    switch(result[i][0]){//天平右边的情况
    case 'u'://右边高
        if(strchr(pRight,c)== NULL)
            return false;
        break;
    case'e'://相等的话
        if(strchr(pRight,c)||strchr(pLeft,c))
            return false;
        break;

    case 'd'://右边低
        if(strchr(pLeft,c)== NULL)
            return false;
        break;

    }

}
return true;

}
int main()
{
   int t;
   cin>>t;
   while(t--){
    for(int i =  0;i < t; i++){
        cin>>Left[i]>>Right[i]>>result[i];//ABCD EFGH even
        for(char c= 'A';c <='L';c++){
        if(isFake(c,true)){//c为假币且为轻的的话为true
            cout<<c<"is the counterfeit coin and it is light.\n";
            break;
        }
        else if(isFake(c,false)){//c为假币但是c为重的
            cout<<c<<"is the counterfeit coin and it is heavy.\n";
            break;

        }

        }

    }

   }

    return 0;
}
//思路正确但有点错误

熄灯问题一

熄灯问题二

递归

递归:
1,一个函数调用其自身,就是递归
2,求 n!的递归函数

int Factorial(int n){
	if(n == 0)
	return 1;
	else
	return n * Factorial(n - 1);
} 

递归和普通函数调用一样是通过栈实现的
递归的作用
1,替代多重循环
2,解决本来就用递归形式定义的问题
3,将问题分解为规模更小的子问题进行求解

汉诺塔问题

在这里插入图片描述
输入:盘子以及A B C
输出:盘子的动向

#include <cstdio>
#include <iostream>
using namespace std;
void hanoi(int n,char src,char mid,char dest){
 if(n == 1){
 	printf("%c->%c",src,dest);
 	return ;
 }	
 else{
 	hanoi(n-1,src,dest,mid);
 	printf("%c->%c",src,dest);
 	hanoi(n-1,mid,src,dest);
 	return;
 }	
}
int main( ){
	int n;
	scanf("%d",&n);
	hanoi(n,'A','B','C');
	return 0; 
} 

N皇后

在这里插入图片描述
在这里插入图片描述

#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
int n;
int queenPos[100];//存放位置
void Nqueen(int k){//在0~k-1行皇后已经摆好的情况下,摆第K行以及其后的皇后
int i;
if(k==n){//k皇后已经摆好了 
	for(int i = 0;i<n;i++){
		printf("%d",queenPos[i]+1);
		return ;
	}
}
 for(int i = 0;i < n;i++){//逐渐尝试第K个皇后的位置 
 	int j;
 	for(int j = 0;j < k;j++){
 		if(queenPos[j]==i||abs(queenPos[j]-i)==abs(k-j)){
 			break;//冲突 则进行下一个位置 
		 }
		 if(j==k){//不冲突 
		 	queenPos[k]=i;
		 	Nqueen(k+1);
			  
		 }
	 }
 } 
		
	
}
int main( ){
	int n;
	scanf("%d",&n);
	Nqueen(0);
	return 0;
}//答案错误
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值