穷举算法
穷举法也称为枚举法、暴力法,通过搜索所有的解空间得到问题的解。
优点:逻辑简单,编写程序简单、可以解决小规模的问题。
缺点:效率不高。
列一下自己在学习算法的时候总结的有代表性的题目,
问题描述 如果一个序列满足下面的性质,我们就将它称为摆动序列: 1. 序列中的所有数都是不大于k的正整数; 2. 序列中至少有两个数。 3. 序列中的数两两不相等; 4. 如果第i – 1个数比第i – 2个数大,则第i个数比第i – 2个数小;如果第i – 1个数比第i – 2个数小,则第i个数比第i – 2个数大。 比如,当k = 3时,有下面几个这样的序列: 1 2 1 3 2 1 2 1 3 2 3 2 3 1 3 1 3 2 一共有8种,给定k,请求出满足上面要求的序列的个数。 输入格式 输入包含了一个整数k。(k<=20) 输出格式 输出一个整数,表示满足要求的序列个数。 样例输入 3 样例输出 8
#include<iostream> using namespace std; int a[25],n,ans; int visit[25]; int IsCan(int num,int k){ //满足摆动序列条件 if(k==1 || k==2) return 1; if(a[k-1]>a[k-2] && num<a[k-2]) return 1; if(a[k-1]<a[k-2] && num>a[k-2]) return 1; return 0; } void dfs(int cur){ //深度优先遍历(cur表示当前填的第几个下标) if(cur>n) return ; for(int i=1;i<=n;i++){ if(!visit[i] && IsCan(i,cur)){ visit[i]=1; a[cur]=i; if(cur>=2) //至少两个数 ans++; dfs(cur+1); //继续判断下标 visit[i]=0; } } } int main(){ cin>>n; dfs(1); cout<<ans<<endl; }
2,3,5,7,11,13,....是素数序列。 类似:7,37,67,97,127,157 这样完全由素数组成的等差数列,叫等差素数数列。 上边的数列公差为30,长度为6。 2004年,格林与华人陶哲轩合作证明了:存在任意长度的素数等差数列。 这是数论领域一项惊人的成果! 有这一理论为基础,请你借助手中的计算机,满怀信心地搜索: 长度为10的等差素数列,其公差最小值是多少? 注意:需要提交的是一个整数,不要填写任何多余的内容和说明文字。
#include <iostream> using namespace std; typedef long long ll; //额外提出(n%2),为下面i+=2服务。 bool isprime(ll n){ if(n <= 1 || (n > 2 && n % 2 == 0)){ return false; } for(ll i = 3; i*i <= n; i += 2){ if(n % i == 0){ return false; } } return true; } int main(){ for(int d = 2; d < 1000; d ++){ for(ll n = 2; n < 1000; ++ n){ if(isprime(n) && isprime(n + d) && isprime(n + 2*d) && isprime(n + 3*d) && isprime(n + 4*d) && isprime(n + 5*d) && isprime(n + 6*d) && isprime(n + 7*d) && isprime(n + 8*d) && isprime(n + 9*d) ){ cout << d << endl; break; } } } return 0; }
四平方和定理,又称为拉格朗日定理: 每个正整数都可以表示为至多4个正整数的平方和。 如果把0包括进去,就正好可以表示为4个数的平方和。 比如: 5 = 0^2 + 0^2 + 1^2 + 2^2 7 = 1^2 + 1^2 + 1^2 + 2^2 (^符号表示乘方的意思) 对于一个给定的正整数,可能存在多种平方和的表示法。 要求你对4个数排序: 0 <= a <= b <= c <= d 并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法 程序输入为一个正整数N (N<5000000) 要求输出4个非负整数,按从小到大排序,中间用空格分开 再例如,输入: 12 则程序应该输出: 0 2 2 2 再例如,输入: 773535 则程序应该输出: 1 1 267 838 资源约定: 峰值内存消耗 < 256M CPU消耗 < 3000ms
1 #include <stdio.h> 2 #include <math.h> 3 4 int main() 5 { 6 int a, b, c, n, flag = 0; 7 double maxN, d; 8 scanf("%d", &n); 9 maxN = sqrt(n); 10 for(a = 0; a <= maxN; a ++){ 11 for(b = a; b <= maxN; b ++){ 12 for(c = b; c <= maxN; c ++){ 13 d = sqrt(n - a*a - b*b - c*c); 14 if(d == (int)d){ 15 printf("%d %d %d %d\n", a, b, c, (int)d); 16 flag = 1; 17 break; 18 } 19 } 20 if(flag) 21 break; 22 } 23 if(flag) 24 break; 25 } 26 return 0; 27 }
1 问题描述 2 Torry从小喜爱数学。一天,老师告诉他,像2、3、5、7……这样的数叫做质数。Torry突然想到一个问题,前10、100、1000、10000……个质数的乘积是多少呢?他把这个问题告诉老师。老师愣住了,一时回答不出来。于是Torry求助于会编程的你,请你算出前n个质数的乘积。不过,考虑到你才接触编程不久,Torry只要你算出这个数模上50000的值。 3 输入格式 4 仅包含一个正整数n,其中n<=100000。 5 输出格式 6 输出一行,即前n个质数的乘积模50000的值。 7 样例输入 8 1 9 样例输出 10 2
1 #include <iostream> 2 3 using namespace std; 4 bool prime(int n) //判断是否为素数 5 { 6 int i; 7 for(i=2;i*i<n;i++) 8 if(n%2==0) break; 9 if(i*i<n) return false; 10 else return true; 11 } 12 int main() 13 { 14 int i,j,n,sum,ans; 15 bool p[100001]={0}; 16 while(cin>>n){ 17 ans = 1; 18 sum = 0; 19 i = 2; 20 while(sum<n){ 21 if(!p[i] && prime(i)){ //判断该数i是否为素数 22 ans = ans*i%50000; 23 sum++; 24 for(j=i+i;j<=100000;j+=i) //去掉不为素数的元素 25 p[j]=true; 26 } 27 i++; 28 } 29 cout<<ans<<endl; 30 } 31 return 0; 32 }
1 问题描述 2 对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能。它们的前几个是: 3 00000 4 00001 5 00010 6 00011 7 00100 8 请按从小到大的顺序输出这32种01串。 9 输入格式 10 本试题没有输入。 11 输出格式 12 输出32行,按从小到大的顺序每行一个长度为5的01串。
1 #include<stdio.h> 2 int main() 3 { int i,j,k,l,m; 4 for(i=0;i<=1;i++){ 5 for(j=0;j<=1;j++){ 6 for(k=0;k<=1;k++){ 7 for(l=0;l<=1;l++){ 8 for(m=0;m<=1;m++){ 9 printf("%d%d%d%d%d\n",i,j,k,l,m); 10 } 11 } 12 } 13 } 14 } 15 return 0; 16 }
1 问题描述 2 求出区间[a,b]中所有整数的质因数分解。 3 输入格式 4 输入两个整数a,b。 5 输出格式 6 每行输出一个数的分解,形如k=a1*a2*a3...(a1<=a2<=a3...,k也是从小到大的)(具体可看样例) 7 样例输入 8 3 10 9 样例输出 10 3=3 11 4=2*2 12 5=5 13 6=2*3 14 7=7 15 8=2*2*2 16 9=3*3 17 10=2*5 18 提示 19 先筛出所有素数,然后再分解。 20 数据规模和约定 21 2<=a<=b<=10000
1 #include <iostream> 2 using namespace std; 3 int isprime(int n) { 4 if(n <= 1) 5 return 0; 6 else if(n == 2 || n == 3) 7 return 1; 8 else { 9 for(int i = 2; i * i < n; i++) { //判断是否为素数 10 if(n % i == 0) { 11 return 0; 12 } 13 } 14 return 1; 15 } 16 } 17 int main() { 18 int a, b; 19 cin >> a >> b; 20 for(int i = a; i <= b; i++) { 21 int temp = i; 22 cout << i << "="; 23 int flag = 0; 24 while(temp != 1) { 25 for(int j = 2; j <= temp; j++) { 26 if(isprime(j) && temp % j == 0) { 27 temp = temp / j; 28 if(flag == 1) 29 cout << "*"; 30 cout << j; 31 flag = 1; 32 break; 33 } 34 } 35 } 36 cout << endl; 37 } 38 return 0; 39 }

浙公网安备 33010602011771号