算法竞赛入门 | 暴力求解法 | 简单枚举

注:最近在学习刘汝明老师的《算法竞赛入门经典》,以下为相关整理的学习笔记内容


“暴力解决”——不用动太多脑筋,把所有可能性都列举出来,然后一一试验。尽管这样的方法显得很“笨”,但却常常是行之有效的。


一、除法

问题描述:输入正整数n,按照从小到大的顺序输出所有形如abcde/fghij=n的表达式,其中a~j恰好为数字0~9的一个排列,2<=n<=79。

样例输入:

62

样例输出:

79546/01283=62

94736/01528=62

分析:枚举0~9的所有排列?没有必要,只需要枚举fghij就可以算出abcde,然后判断是否所有数字都不相同即可。不仅程序简单而且枚举量也从10!=3628800降至不到1万。

由此可见,即使采用暴力枚举,也是需要认真分析问题的。


#include
#include 
using namespace std;
bool check(int i,int j)  
{  
   int n[10],flag=1;  
   n[0]=i%10,n[1]=i/10%10,n[2]=i/100%10,n[3]=i/1000%10,n[4]=i/10000%10;  
   n[5]=j%10,n[6]=j/10%10,n[7]=j/100%10,n[8]=j/1000%10,n[9]=j/10000%10;  
   sort(n,n+10);  
   for(int i=0;i<10;i++)  
   {  
       if(n[i]!=i)  
       {  
           flag=0;  
           break;  
       }  
   }  
   if(flag==1)  
    return true;  
   else  
    return false;  
} 
int main()
{
	int n;
	cin>>n;
	int i,j;
	for(i=1234;i<=98765;i++)
	{
		j = i*n;
		if(j>=10234&&j<=98765)
		{
			if(check(i,j)==true)
			{
				
				if(i/10000%10&&j/10000%10)	
					cout<二、最大乘积

问题描述:输入n个元素组成的序列S,你需要找出一个乘积最大的连续子序列。如果这个最大的乘积不是正数,应输出-1(表示无解)。-1<=n<=18,-10<=Si<=10。

样例输入:

3

2 4 -3

2 5 -1  2 -1

样例输出:

8

30

分析:连续子序列有两个要素:起点和终点,因此只需枚举起点和终点即可。由于每个元素的绝对值不超过10,一共又不超过18个元素,最大可能的乘积不会超过10^18,可以用long long存下。

#include
using namespace std;

int main()
{
	long long s[20],num[20];
	int n;
	long long max;
	while(~scanf("%d",&n))
	{
		s[0]=1;
		for(int i=1;i<=n;i++)
		{
			cin>>num[i];
			s[i] = s[i-1]*num[i];
			
		}
		
		for(int i=1;i<=n;i++)
		{
			for(int j=i;j<=n;j++)
			{
				
				if(s[j]/s[j-i]>max)
				max = s[j]/s[j-i];
			}
			
		}
		
		if(max<0)
			max = -1;
		cout<

三、分数拆分

输入正整数k,找到所有的正整数x>=y,使得1/k=1/x + 1/y; 
样例输入: 

12 
样例输出: 

1/2 = 1/6 + 1/3 
1/2 = 1/4 + 1/4 

1/12 = 1/156 + 1/13 
1/12 = 1/84 + 1/14 
1/12 = 1/60 + 1/15 
1/12 = 1/48 + 1/16 
1/12 = 1/36 + 1/18 
1/12 = 1/30 + 1/20 
1/12 = 1/28 + 1/21 
1/12 = 1/24 + 1/24 
从1/12=1/156+1/13可以看出,x可以比y大很多。由于x>=y,有1/x<=1/y,因此1/k-1/y<=1/y,即y<=2*k.这样,只需要在2*k范围之内枚举y,然后根据y尝试计算出x即可。

可以由题目推导得到 1/k<=2/y  即y<=2k

拆解题目的公式得到(y-k)/ky==1/x

#include
using namespace std;
int main()
{
	int k;
	cin>>k;
	for(int y=k+1;y<=2*k;y++)
	{
		if((k*y%(y-k))==0)
		{
			int x=k*y/(y-k);
			cout<<"1/"<

你可能感兴趣的:(算法竞赛入门 | 暴力求解法 | 简单枚举)