暴力通用算法

本文详细介绍了暴力求解法在不同问题中的应用,包括除法问题、寻找最大子序列乘积、分数拆分和数据排列。同时,文章探讨了回溯法在排列问题和子集问题求解中的高效性,并讨论了如何在无约束条件下使用回溯法求最优解。此外,还涉及到了隐式图的最短路径问题和迭代加深搜索在特定问题上的运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

暴力求解法

暴力枚举之除法

将0-9分成五个五个一组,abcde/fghij=n,指定n求出所有符合的元素,从小到大输出。
从01234开始枚举。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
   
   
 int n,kase=0;
 while(scanf("%d",&n)==1 && n)
 {
   
   
     if(kase++)printf("\n");
     int cnt=0;
     for(int fghij=1234;;fghij++)
     {
   
   
         char buf[99];
         int abcde=n*fghij;
         sprintf(buf,"%05d%05d",abcde,fghij);//五个一组输出到buf中
         if(strlen(buf)>10) break;
         sort(buf,buf+10);
         bool ok=true;
         for(int i=0;i<10;i++)
         {
   
   
             if(buf[i]!='0'+i)ok=false;
         }
         if(ok)
         {
   
   
             printf("%05d / %05d = %d\n",abcde,fghij,n);
             cnt++}

     }
     if(!cnt)printf("There are no solutions for %d.\n", n);
}
return 0;
}

暴力枚举之寻找最大子序列乘积

在连续子序列之中,寻找乘积最大的序列,遍历所有的起点和终点即可。

#include<iostream>
using namespace std;

int main() {
   
   
int S[20], kase = 0, n;
while(cin >> n && n) {
   
   
  for(int i = 0; i < n; i++) cin >> S[i];
  long long ans = 0;
  for(int i = 0; i < n; i++) //起点
  {
   
   
    long long v = 1;
    for(int j = i; j < n; j++) //终点
    {
   
   
      v *= S[j];
      if(v > ans) ans = v;
    }
  }
  cout << "Case #" << ++kase << ": The maximum product is " << ans << ".\n\n";
}
return 0;
}

暴力枚举之分数拆分

输入正整数k,找到所有正整数x>=y,使得1/k=1/x+1/y
从y=k+1开始遍历,最后一个表达式肯定是y=2*k=x.

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
int main()
{
   
   
 int k;
 while(cin>>k)
 {
   
   
     vector<int> sy,sx;
     int x;
     for(int y=k+1;y<=2*k;y++)
     {
   
   

         x=(k*y)/(y-k);
         if(x>=y && (k*y)%(y-k)==0)
           {
   
   
             sx.push_back(x);
             sy.push_back(y);
            }
         if(x<y) break;
     }
     cout<<sx.size()<<endl;
     for(int i=0;i<sx.size();i++)
     printf("1/%d = 1/%d + 1/%d\n",k,sx[i],sy[i]);

 }
return 0;
}

暴力枚举之数据排列(递归1-n的元素字典序排列)

1-n个元素,不含重复元素存放在数组中,第一个元素有n种可能,每一种可能对应的下一个元素又有n-1种可能…符合递归的思想。一共有n的阶乘种排列。
像这种方法就是递归枚举法,工作方式就是解答树,第一层一个节点,第二层n个节点,第三次n(n-1)个节点,第n层n的阶乘个节点,就是栈帧的调用方式。

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
void print_permutation(int n,int* A,int cur)
{
   
   
 if(cur==n)
 {
   
   
     for(int i=0;i<n;i++)printf("%d",A[i]);
     printf("\n");
 }
 else for(int i=1;i<=n;i++)//从1-n开始选数,遍历,每个数都插入到该位置
 {
   
   
     int ok=1;
     for(int j=0;j<cur;j++)
         if(A[j]==i)ok=0;
     if(ok){
   
   
         A[cur]=i;
         print_permutation(n,A,cur+1);
           }          
 }
}
int main()
{
   
   
 int n;
 cin>>n;
 int A[1000];
 memset(A,0,sizeof(A));
 print_permutation(n,A,0);
 return 0;
}

暴力枚举之数据排列(STL中算法库next_permutation函数)

可以包含重复元素。

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
   
   
 int n,p[10];
 cin>>n;
 for(int i=0;i<n;i++)
     cin>>p[i];
 sort(p,p+n);
 do{
   
   
     for(int i=0;i<n;i++)
         cout<<p[i];
     cout<<endl;
 }while(next_permutation(p,p+n));
 return 0;
}

暴力枚举之求子集(二进制法,当n<15时采用)

给定一个集合,不重复,求出该集合的所有子集,包含空集。
可以定义一个与该集合相同长度的数组,每个数组的元素为0或1,遍历0~2^n - 1(即i<<n-1)次即可得到所有情况下的子集编码。
将这个子集编码分别与所有元素进行按位与,为1即可输出该元素。就是将所有元素在数组中与子集编码相同的位置置为1(1<<i,代表将第几号位置置1,其他位置为0,本来就不用考虑其他位置),这样就只与子集编码有关了,是1即可输出。(注意是从右向左进行与,因为最右边值最小)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值