一些大佬眼中,暴力解决称不上算法,但是对于我这种菜鸡来说..........还是从暴力开始记录开始比较恰当
这篇主要记一下简单枚举。
枚举,基于逐个尝试答案的一种问题求解策略。
所谓枚举,并不是直接暴力循环,而是先思考,缩小枚举范围,不然就算求出来也是超时了,除非是暴力杯的填空题,不然就没什么意义了。尽管暴力枚举不用动太大脑筋,但是对问题进行一定的分析往往会是算法更加简洁高效。
例子一:POJ2810 完美立方
形如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所在位置分别用实际求出四元组值代入。
思路: 四重循环枚举abcd, a在最外,d在最里面,每一层由小到大。主要bcd的范围。
#include
#include
using namespace std;
int main()
{
int N;
scanf("%d",&N);
for(int a = 2; a <= N;a++)
for(int b = 2; b < a;b++)
for(int c = b; c < a;c++)
for(int d = c; d < a; d++)
if(a*a*a == b*b*b + c*c*c + d*d*d )
printf("Cube = %d, Tripe = (%d,%d,%d)\n",a,b,c,d);
return 0;
}
例子二:POJ:1006--BIORHYTHM(生理周期计算)
人生来就有三个生理周期,分别为体力、感情和智力周期,它们的周期长度为23 天、 28 天和33 天。
每一个周期中有一天是高峰。在高峰这天,人会在相应的方面表现出色。
例如,智力周期的高峰,人会思维敏捷,精力容易高度集中。
因为三个周期的周长不同,所以通常三个周期的高峰不会落在同一天。
对于每个人,我们想知道何时三个高峰落在同一天。
对于每个周期,我们会给出从当前年份的第一天开始,到出现高峰的天数(不一定是第一次高峰出现的时间)。
你的任务是给定一个从当年第一天开始数的天数,输出从给定时间开始(不包括给定时间)下一次三个高峰落在同一天的时间(距给定时间的天数)。
例如:给定时间为10,下次出现三个高峰同天的时间是12,则输出2(注意这里不是3)。
思路:从d+1天开始枚举,看是否满足。我这个程序并不严谨,d应该小于365,我并没有限制。
#include#include using namespace std; int main() { int p,e,i,d,caseNo=0; while(cin>>p>>e>>i>>d && p!=-1) { ++caseNo; 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 " << caseNo <<" the next tripe peak occurs in"< } return 0; }
例子三 POJ1013 称硬币
懒得打字了,直接复制题目过来,大意是有十二枚硬币,十一枚是真的,称三次判断出假币并确定这个假的比真的沉还是轻。
Sally Jones has a dozen Voyageur silver dollars. However, only eleven of the coins are true silver dollars; one coin is counterfeit even though its color and size make it indistinguishable from the real silver dollars. The counterfeit coin has a different weight from the other coins but Sally does not know if it is heavier or lighter than the real coins.
Happily, Sally has a friend who loans her a very accurate balance scale. The friend will permit Sally three weighings to find the counterfeit coin. For instance, if Sally weighs two coins against each other and the scales balance then she knows these two coins are true. Now if Sally weighs
one of the true coins against a third coin and the scales do not balance then Sally knows the third coin is counterfeit and she can tell whether it is light or heavy depending on whether the balance on which it is placed goes up or down, respectively.
By choosing her weighings carefully, Sally is able to ensure that she will find the counterfeit coin with exactly three weighings.
输入样例
1
ABCD EFGH even
ABCI EFJK up
ABIJ EFGH even
输出样例
K is the counterfeit coin and it is light.
思路:对于每一个硬币,先假设这个是轻的,看是否符合结果,如果符合就ok。不符合就假设是重的,再全试一遍。
#include
#include
using namespace std;
char Left[3][7];// the coins on the left
char Right[3][7];//the coins on the right
char result[3][7];
bool IsFake (char c,bool light)//if the fake is 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;
}
int main()
{
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;
}
不得不吐槽,csdn这个页面太不好用了。