算法基础_枚举

Posted Robin5

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法基础_枚举相关的知识,希望对你有一定的参考价值。

枚举:基于逐个尝试答案的一种文体求解策略


 1. 完美立方

题目描述:

形如a^3= b^3 + c^3 + d^3的等式被称为完美立方等式。例如
12^3= 6^3 + 8^3 + 10^3 。编写一个程序,对任给的正整数N
(N≤100),寻找所有的四元组(a, b, c, d),使得a^3 = b^3 +
c^3 + d^3,其中a,b,c,d 大于1 , 小于等于N,且b<=c<=d。
输入
一个正整数N (N≤100)。
输出
每行输出一个完美立方。输出格式为:
Cube = a, Triple = (b,c,d)
其中a,b,c,d所在位置分别用实际求出四元组值代入。
要求a从小到大输出。  

解题思路:

四重循环枚举a,b,c,d
a在最外层,d在最里层,每一层都是从小到大枚举,
a 范围 [2, N]
b 范围 [2, a-1]
c 范围 [b, a-1]
d 范围 [c, a-1]

代码示例:

// 完美立方
# include <stdio.h> 

int main(void)
{
	int a,b,c,d;
	int N;
	scanf("%d",&N);
	
	for (a=2; a<=N; a++)
		for (b=2; b<=a-1; b++)
			for (c=b; c<=a-1; c++)
				for (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;
}

2. 生理周期

题目描述:

人生来就有三个生理周期,分别为体力、感情和智力周期, 它们的周期长度为23天、28天和33天。每一个周期中有一天 是高峰。在高峰这天,人会在相应的方面表现出色。 例如,智力周期的高峰,人会思维敏捷,精力容易高度集中。 因为三个周期的周长不同,所以通常三个周期的高峰不会落在 同一天。对于每个人,我们想知道何时三个高峰落在同一天。 对于每个周期,我们会给出从当前年份的第一天开始, 到出现高峰的天数(不一定是第一次高峰出现的时间)。
 你的任务是给定一个从当年第一天开始数的天数, 输出从给定时间开始(不包括给定时间)下一次三个高峰
 落在同一天的时间(距给定时间的天数)。
 例如:给定时间为10,下次出现三个高峰同天的时间是12, 则输出2(注意这里不是3)。输入有多组数据,以一行-1结束。

解题思路:

从第d+1天开始, 一直试到第21252天,对其中每一天看是否满足
当前日期与 p e i差值分别能被 23 28 33 同时整除

代码示例:

// 生理周期 
# include <iostream>
using namespace std;

int main(void)
{
	int p,e,i,d,j, num=0;
	// 没必要全部枚举 
	while (cin>>p>>e>>i>>d && p!=-1)
	{
		++num;
		for (j=d+1; (j-p)%23; j++); // 先找到第一个是23倍数的日期 
		for (     ; (j-e)%28; j+=23); // 再按照23的增量查看是否是28的倍数 
		for (     ; (j-i)%33; j+=23*28); // 最后再以23*28的增量确定是否是33 的倍数 
		cout<<"Case"<<num<<": the next triple peak occours in";
		cout<<j-d<<"days"<<endl; // 最后输出 j d 之间的间隔  
	}
	
	return 0;
 } 

3. 称硬币

问题描述:

有12枚硬币,其中有11枚真币和1枚假币。
假币和真币重量不同,但不知道假币比真币轻还是重。
现在,用一架天平称了这些币三次,告诉你称的结果,
请你找出假币并且确定假币是轻还是重。

输入样例:
1
ABCD EFGH even  //天平左边是ABCD四枚,右边是EFGH,平衡。
ABCI EFJK up  //右边翘起来
ABIJ EFGH even  //相同
//表示的都是右边重量

解题思路:

		对于每一枚硬币先假设它是轻的,看是否符合称量结果。
		如果符合,则问题解决。否则,假设他是重的,看是否
		符合称量结果。把所有硬币都试一遍,一定能找到特殊硬币。

代码示例:

// 称硬币
# include <iostream>
# include <cstring> 
using namespace std;
char Left[3][7]; // 天平左边硬币 
char Right[3][7]; // 天平右边硬币 
char result[3][7]; // 结果 
bool IsFake(char c, bool light);

int main(void)
{
	int t; 
	cin>>t;
	while(t--)
	{
		for (int i = 0; i<3; i++)
			cin>>Left[i]>>Right[i]>>result[i];
		for (char c=‘A‘; c<=‘L‘; c++)
		{
			if (IsFake(c, true))
			{
				cout<<c<<" is the counterfeit coin and it is light.\n";
				break;
			}
			else if(IsFake(c, false))
			{
				cout<<c<<" is the counterfeit coin and it is heavy.\n";
				break;
			}
		}
	}
	return 0;
}

bool IsFake(char c, bool light)
// 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(pLeft,c) || strchr(pRight,c))
						return false;
					  break;
			case ‘d‘: if(strchr(pLeft,c) == NULL)
						return false;
					  break;
		}
		 
	} 
	return true;
} 

  

 

RRR

以上是关于算法基础_枚举的主要内容,如果未能解决你的问题,请参考以下文章

《算法零基础》第10讲:因子分解和枚举(部分)

算法基础 —— 枚举

算法入门 01线性枚举(简单 - 第二题)LeetCode 557

零基础逆向工程40_Win32_14_枚举窗口_模拟鼠标键盘

Java版算法思想递归&分治&回溯&枚举&基础数论

Java版算法思想递归&分治&回溯&枚举&基础数论