枚举,顾名思义,就是将所有情况都举出,并判断其是否符合题目条件。所以枚举的基本方法便是分析题意后,找到一个合适的维度列举每一个元素,以完成题目。其中如何找到一个合适的维度来进行枚举便是其中的最大难点。
(1)时间条件
枚举范围小或时间无限制(蓝桥杯填空题)
一般来说主流的OJ当中,1000ms的时间限制下可以运行操作数为107以内的运算(通常106以内较为保险),所以在采用枚举方法之前最好看一下数据范围,确保整个程序的执行操作数不会超过106-107这个量级,如果超过了就尝试更换枚举的维度或者使用其他算法吧。
(2)编程上的实现条件
在编程实现上,一般来说暴力枚举需要两个条件,一是枚举的范围一般需要连续,如果枚举范围是离散的,那么一般很难使用for循环枚举出所有状态,也就不能保证解的完整性(不过有些时候数据看似离散,但实际上可以经过处理变得连续,如构造数组)。第二个条件是枚举内容需要已知,不能在枚举到某个地方的时候出现未知(不过这个一般都被满足)。
(1)简单的暴力枚举一般只适用于解决简单的问题
(2)难以求出或范围特别大,明显超时(数论等)
https://www.luogu.com.cn/problem/P1403
(1)找到枚举变量**(尽量由已知推未知)**
(2)找到并尽量缩小范围(根据题意但无需太过精确,可以过大,条件在if中判断即可)
(3)依据题意进行操作**(尽量剪枝)**
(1)枚举变量
按位数0-9(一),按数字(二),或离散时构造数组(一、2)
尽量由已知推未知:一般有一个变量可以直接运算得出。尽量用乘法(二、1)
(2)常见限制
位数、位数字出现次数
(3)取位方法
//取b由低到高位
for(int i = 0;b != 0;i++)
{
a[i] = b % 10;
b /= 10;
}
(4)记录位数字出现个数
使用数组a[10],a[i]代表数字i出现了a[i]次
(5)从小到大
从小到大枚举(一、4)
适用于条件偏向于位
org[i]代表org[i]已出现
https://blog.csdn.net/weixin_38172774/article/details/87354310
https://blog.csdn.net/weixin_38172774/article/details/87354310
思路:先找一个,然后继续找另一个
枚举变量:离散可构造数组
https://blog.csdn.net/weixin_38172774/article/details/87354310
https://blog.csdn.net/weixin_38172774/article/details/87354310
从小到大:从小到大枚举
#include
#include
using namespace std;
int main() {
int n,temp;
int a,b,c;
//注意类型!
double d;
cin >> n ;
for(a = 0 ; a*a <= n; a++){
for(b = a ; b*b <= n; b++){
for(c = b ; c*c <= n; c++){
d = sqrt(n-a*a-b*b-c*c);
//判断d是否为整数!
if(d == int(d)){
cout << a<<" "<
https://blog.csdn.net/weixin_38172774/article/details/87354310
注意判断是否为6位数
适用于数字x,y或数字并非刚好为临界(如1111)
https://blog.csdn.net/weixin_38172774/article/details/87354310
b/a = n得b = a * n;避免小数的出现,自然就节约判断了
可以确定:a来说最小为01234,最大为98765
由于题目中已经给出,最多有24根火柴,而等号和加号各用4根的前提下,A\B\C三个数则总共只有20根火柴,数据范围较小,可以用枚举法枚举A、B。这个时候我们发现,0-9这10个数字所用的火柴数为:6,2,5,5,4,5,6,3,7,6,很明显数字1用的火柴棒最少只要2根,不妨让B为1,那么A和C最多可以使用18根火柴,而C>=A,满足条件的A的最大取值为1111。所以枚举A和B的范围是从0~1111。(应该是过大了)
#include
#include
int a[2223]= {6,2,5,5,4,5,6,3,7,6};//前10需要的火柴数目
const int b[10]= {6,2,5,5,4,5,6,3,7,6};//定义b数组的值,不可改变
int need(int n)
{
int t, num;
num=0;
if(n==0) return 6;
while(n>0)
{
t=n%10;
num+=b[t];//统计数字并且把这些数字所需要的火柴数目加起来
n/=10;//跳过最后一个数字
}
return num;
}
int main( )
{
int n,i,j,A,B,C,D,sum;
scanf("%d",&n);
sum=0;
//预处理
for(i=10; i<2223; i++)
a[i]=need(i);//把每个数字需要的火柴数目赋值
for(i=0; i<=1111; i++)
{
for(j=0; j<=1111; j++)
{
A=a[i];//A的火柴数目
B=a[j];//B的火柴数目
C=n-4-A-B;//C的火柴数目
D=a[i+j];//等式的实现是通过i+j=(i+j)
if(D==C) sum++;//如果符合等式
}
}
printf("%d\n",sum);
return 0;
}
y的范围为 k 注意判断x是否为整数 k*y%(y-k)) == 0 https://www.cnblogs.com/rhythmic/p/5980017.html 依据题意即可 https://blog.csdn.net/weixin_38172774/article/details/87354310 http://acm.hdu.edu.cn/showproblem.php?pid=1422 https://www.cnblogs.com/rhythmic/p/5980017.html 哪里用到那个结论了? 对最矮进行枚举 https://www.luogu.com.cn/problem/P3650三、模拟+暴力枚举
技巧
1、机器人繁殖
#include
2、HDU1422 重温世界杯
#include
3、滑雪课程设计