问题标题: 酷町堂:哪位大佬能给我讲一讲枚举???

0
0

0
已采纳
刘英杰
刘英杰
新手天翼
新手天翼

这帮人,要不从网上复制,要不水帖(是友军)

我来给一个比较标准的解释

枚举,由“枚”和“举”俩字组成

“枚”意思是单个

“举”意思是列举

枚举就是将很多可能性统统列出来,最后找出答案

枚举的优点是稳定性强,缺点是时间相对与其他算法较长

例:现在,笼子里有两种动物,一种是鸡,一种是兔,一只兔有四条腿,一只鸡有两条腿

笼子里,可以数出30个头(就是30个动物)和100条腿,问鸡有几只,兔有几只?

分析:这道题属于典型的枚举(当然,数学学好了也能用假设),所以,代码如下:

#include<iostream>

using namespace std;

int main()//框架部分

{

    int i,j;//定义两个循环变量i,j用于列举

    for(i=1;i<=30;i++)//i从1到30,表示可能有兔的数量

    {

        j=30-i;//每次循环,保证鸡(j)与兔(i)的和为30;

        if(j*2+i*4==100)//判断,如果鸡的只数乘2+兔的只书乘4正好等于100,说明本次循环的鸡与兔的成立

            break;//条件成立后,跳出循环

    }

    cout<<"鸡的只数有"<<j<<"只"<<endl;

    cout<<"兔的只数有"<<i<<"只";//输出

    return 0;

}

最终结果,鸡有10只,兔有20只

根据样例,我们发现,枚举是一种简单常用易掌握的算法

只要在循环中找到那个可能性即可

PS:本人入堂不就,穷的一批,求采纳,求关注,您的采纳和关注就是对我最大的支持!

1
0
0
赵朗
赵朗
高级光能
高级光能

枚举你没学可以自己查查

不想在这里查百度

0
0
0
曲天歌
曲天歌
高级光能
高级光能

枚举

编辑词条

枚举枚举(2)

枚举 (enumeration),是值类型的一种特殊形式,是一个被命名的整型常数的集合,它从 System.Enum 继承,并为基础基元类型的值提供备用名称。

枚举类型有名称、基础类型和一组字段。基础类型必须是一个内置的有符号(或无符号)整数类型(如 Byte、Int32 或 UInt64)。字段是静态文本字段,其中的每一个字段都表示常数。所使用的语言给每个字段都分配一个基础类型的特定值。

快速导航

中文名

枚举

定义

被命名的整型常数的集合

外文名

enumeration

类型

值类型


1词语介绍

编辑

【词目】:枚举

【拼音】:méijǔ

【释义】:指一一列举。

【语出】:

《书·无逸》:“其在祖甲,不义惟王。”

蔡沈传:“及云者,因其先后次第而枚举之辞也。”

【基本解释】

[enumerate]一一列举

【详细解释】

一一列举。

2常数集合

编辑

枚举(enum)

枚举在C/C++/c#中,是一个被命名的整型常数的集合,枚举在日常生活中很常见。

例如表示星期的SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,

SATURDAY,就是一个枚举。

枚举的说明与结构和联合相似,其形式为:

enum枚举名{

标识符[=整型常数],

标识符[=整型常数],

...

标识符[=整型常数]

}枚举变量;

如果枚举没有初始化,即省掉"=整型常数"时,则从第一个标识符开始,顺

次赋给标识符0,1,2,...。但当枚举中的某个成员赋值后,其后的成员按依次

加1的规则确定其值。

例如下列枚举说明后,x1,x2,x3,x4的值分别为0,1,2,3。

enumNum{x1,x2,x3,x4}x;

当定义改变成:

enumNum

{

x1,

x2=0,

x3=50,

x4

}x;

则x1=0,x2=0,x3=50,x4=51

注意:

1.枚举中每个成员(标识符)结束符是",",不是";",最后一个成员可省略

","。

2.初始化时可以赋负数,以后的标识符仍依次加1。

3.枚举变量只能取枚举说明结构中的某个标识符常量。

例如:

enumNum

{

x1=5,

x2,

x3,

x4

};

enumNumx=x3;

此时,枚举变量x实际上是7。

枚举类型变量的赋值和使用

枚举类型在使用中有以下规定:

1.枚举值是常量,不是变量。不能在程序中用赋值语句再对它赋值。例如对枚举weekday的元素再作以下赋值:sun=5;mon=2;sun=mon;都是错误的。

2.枚举元素本身由系统定义了一个表示序号的数值,从0开始顺序定义为0,1,2…。如在weekday中,sun值为0,mon值为1,…,sat值为6。

main(){

enumweekday

{sun,mon,tue,wed,thu,fri,sat}a,b,c;

a=sun;

b=mon;

c=tue;

printf("%d,%d,%d",a,b,c);

}

3.只能把枚举值赋予枚举变量,不能把元素的数值直接赋予枚举变量。如:a=sun;b=mon;是正确的。而:a=0;b=1;是错误的。如一定要把数值赋予枚举变量,则必须用强制类型转换,如:a=(enumweekday)2;其意义是将顺序号为2的枚举元素赋予枚举变量a,相当于:a=tue;还应该说明的是枚举元素不是字符常量也不是字符串常量,使用时不要加单、双引号

main(){

enumbody

{a,b,c,d}month,j;

inti;

j=a;

for(i=1;i<=30;i++){

month[i]

j++;

if(j>d)j=a;

}

for(i=1;i<=30;i++){

switch(month[i]

{

casea:printf("%2d%c\t",i,'a');break;

caseb:printf("%2d%c\t",i,'b');break;

casec:printf("%2d%c\t",i,'c');break;

cased:printf("%2d%c\t",i,'d');break;

default:break;

}

}

printf("\n");

}

10个数字,任意取出不相等的5个数字,

谁还记得这个算法的公式????????

javascript有什么好的计算方法??

mn*(n-1)*(n-2)*...*(n-m+1)n!

C=---------------------------------------------=--------------------------

nm*(m-1)*(m-2)*...*3*2*1m!*(n-m)!

这个是公式,但是对枚举作用不大,还是要遍历循环才行.

这就需要一个好的算法

3数值计算

编辑

枚举(pascal)

随着计算机的不断普及,程序不仅只用于数值计算,还更广泛地用于处理非数值的数据。例如:性别、月份、星期几、颜色、单位名、学历、职业等,都不是数值数据。在其它程序设计语言中,一般用一个数值来代表某一状态,这种处理方法不直观,易读性差。如果能在程序中用自然语言中有相应含义的单词来代表某一状态,则程序就很容易阅读和理解。也就是说,事先考虑到某一变量可能取的值,尽量用自然语言中含义清楚的单词来表示它的每一个值,这种方法称为枚举方法,用这种方法定义的类型称枚举类型。

type

daytype=(sun,mon,tue,wed,thu,fri,sat);

C#中的枚举

枚举类型是一种的值类型,它用于声明一组命名的常数。

(1)枚举的声明:枚举声明用于声明新的枚举类型。

访问修辞符enum枚举名:基础类型

{

枚举成员

}

基础类型必须能够表示该枚举中定义的所有枚举数值。枚举声明可以显式地声明byte、sbyte、short、ushort、int、uint、long或ulong类型作为对应的基础类型。没有显式地声明基础类型的枚举声明意味着所对应的基础类型是int。

(2)枚举成员

枚举成员是该枚举类型的命名常数。任意两个枚举成员不能具有相同的名称。每个枚举成员均具有相关联的常数值。此值的类型就是枚举的基础类型。每个枚举成员的常数值必须在该枚举的基础类型的范围之内。

示例:

public enum TimeofDay:uint

{

Morning=-3,

Afternoon=-2,

Evening=-1

}

产生编译时错误,原因是常数值 -1、-2 和 –3 不在基础整型 uint 的范围内。

(3)枚举成员默认值

在枚举类型中声明的第一个枚举成员它的默值为零。

以后的枚举成员值是将前一个枚举成员(按照文本顺序)的值加 1 得到的。这样增加后的值必须在该基础类型可表示的值的范围内;否则,会出现编译时错误。

示例:

public enum TimeofDay:uint

{

Morning,

Afternoon,

Evening

}

Morning的值为0,Afternoon的值为1,Evening的值为2。

(4)为枚举成员显示赋值

允许多个枚举成员有相同的值.

没有显示赋值的枚举成员的值,总是前一个枚举成员的值+1.

示例

public enum Number

{

a=1,

b,

c=1,

d

}

b的值为2,d的值为2.

注意:以上枚举值都不能超过它的基础类型范围。否则会报错.

(5)枚举类型与基础类型的转换

基础类型不能隐式转换为枚举类型

枚举类型也不能隐式转换为基础类型

示例:

public enum Number

{

a,

b,

c,

d

}

class Test

{

public static void Main()

{

int i=Number.a;//错误,要强制类型转换(int)Number.a

Number n;

n=2 //错误,要强制类型转换(Number)2

}

}

(6)System.Enum类型

System.Enum 类型是所有枚举类型的抽象基类,并且从 System.Enum 继承的成员在任何枚举类型中都可用。

System.Enum 本身不是枚举类型。相反,它是一个类类型,所有枚举类型都是从它派生的。

System.Enum 从类型 System.ValueType派生

(7)使用枚举类型

using System;

public enum TimeofDay

{

Morning,

Afternoon,

Evening

} class Test

{

static void WriteGreeting(TimeofDay timeofDay)

{

switch(timeofDay)

{

case TimeofDay.Morning:

Console.WriteLine("good morning");

break;

case TimeofDay.Afternoon:

Console.WriteLine("good afternoon");

break;

case TimeofDay.Evening:

Console.WriteLine("good evening");

break;

}

}

static void Main()

{

WriteGreeting(TimeofDay.Morning);

WriteGreeting(TimeofDay.Evening);

WriteGreeting(TimeofDay.Afternoon);

}

}[1]

4枚举排列

编辑

1~n全排列

给定一整数n,要按照字典序从小到大的顺序枚举输出前n个数(1-n)的全排列。例如:n=3时,枚举排列结果是:(1,2,3)、(1,3,2)、(2,1,3)、(2,3,1)、(3,1,2)、(3,2,1)。以下是c语言源码实现该算法:

------------------------------------c源码----------------------------------------

#include

#include

voidprint_permutation(intn,int*A,intcur){

inti,j;

if(cur==n){

for(i=0;i

printf("%d",A[i]);

printf("\n");

}

elsefor(i=1;i<=n;i++){

intok=1;

for(j=0;j

if(A[j]==i)

ok=0;

}

if(ok){

A[cur]=i;

print_permutation(n,A,cur+1);//递归调用

}

}

}

voidmain(){

intn;

intA[1000];

printf("inputthen:");

scanf("%d",&n);

print_permutation(n,A,0);

printf("timeused:%.2lf\n",(double)clock()/CLOCKS_PER_SEC);//测试程序运行时间

}

------------------------------------c源码----------------------------------------

可重集全排列

输入数组P,并按字典序输出数组P各元素的全排列到A(注意:P有序),例如P序列为:112,则对应的排序结果为:(1,1,2)、(1,2,1)、(2,1,1)。以下是该算法的c源码,P数组长度可以自己调整。

------------------------------------c源码----------------------------------------

#include

#include

voidprint_permutation(intn,int*P,int*A,intcur){

inti,j;

if(cur==n){

for(i=0;i

printf("%d",A[i]);

printf("\n");

}

elsefor(i=0;i

if(!i||P[i]!=P[i-1]){

intc1=0,c2=0;

for(j=0;j

if(A[j]==P[i])

c1++;

}

for(j=0;j

if(P[i]==P[j])

c2++;

}

if(c1

A[cur]=P[i];

print_permutation(n,P,A,cur+1);//递归调用

}

}

}

}

voidmain(){

intn,m;

intA[1000];

intP;//可以自己修改

inti=0;

while(scanf("%d",&m)==1){

P[i]=m;

i++;

}

n=i;

print_permutation(n,P,A,0);

printf("timeused:%.2lf\n",(double)clock()/CLOCKS_PER_SEC);

}

------------------------------------c源码----------------------------------------

5词条图册

  • 枚举

 

 

 

 

 

 

 

 

什么是枚举

 

 

    枚举,顾名思义,就是用最笨的方法,去解决问题(暴力枚举),一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。这两种类型经常(但不总是)重叠。

    枚举算法是我们在日常中使用到的最多的一个算法,它的核心思想就是:

枚举所有的可能

 

 

    枚举法的本质就是从所有候选答案中去搜索正确的解,使用该算法需要满足两个条件:(1)可预先确定候选答案的数量;(2)候选答案的范围在求解之前必须有一个确定的集合。

接下来几道题可以让你更加的了解枚举

1.楼层编号:

    题目描述:

    小林在NOIP比赛期间住在“新世界”酒店。和其他酒店不一样的是,这个酒店每天都有一个高能的数字t,这个数字在楼层中是不会出现的,以t=3为例,则3、13、31、33等楼层是不存在的,楼层编号为1,2,4,5,……所以实际上的4楼才是3楼
    已知小林预定了编号为m层的房间,并且当天高能数字是t,现在他想知道房间所在的真实楼层是多少

输入描述

    一行两个整数m和t,1<=m<=100000,0<=t<=9,保证m对t合法

输出描述

    一行一个整数,表示真实楼层

样例输入

14 3

样例输出

12

思路:

    1.包含这个高能数字的楼层一定不会出现,则有算法如下

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
bool s(int a,int b){  while(a!=0){    if(a%10==b){      return false;    }    a/=10;  }  return true;}

    2.用for循环对sum进行累加,若不包含高能数字(即s(i,高能数字)=true)则sum++

  •  
  •  
  •  
  •  
  •  
  •  
  for(int i=1;i<=m;i++){    if(s(i,t)){      sum++;    }  }  cout<<sum

代码:

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
#include <iostream>using namespace std;bool s(int a,int b){  while(a!=0){    if(a%10==b){      return false;    }    a/=10;  }  return true;}int main(){  int m,t,sum=0;  cin>>m>>t;  for(int i=1;i<=m;i++){    if(s(i,t)){      sum++;    }  }  cout<<sum;  return 0;}

 

2.乘法交换律(暴力枚举)

题目描述

    由4个不同的数字,组成的一个乘法算式,它们的乘积仍然由这4个数字组成。

比如:

    210 x 6 = 1260

    8 x 473 = 3784

    27 x 81 = 2187

    都符合要求。

    如果满足乘法交换律的算式算作同一种情况,那么,包含上边已列出的3种情况,一共有多少种满足要求的算式。

思路:

    暴力枚举,四重循环, abcd的值分别从0到9开始 ,然后判断abcd不能相等,然后在不相等的条件下进行乘法运算。乘法运算分为两种情况

a * bcd 和 ab * cd

    abcd分别从0-9开始遍历,第一种情况不会出现重复,但第二种情况可能会出现重复,一开始觉得重复会发生在ab大于50 的情况,结果发现 35 和41 也会重复,所以就直接全部遍历再除2解决

判断结果是否和原来的数字组成相同用的最直观的思路,先两个数字都排序,然后依次遍历是否相等,反正就4位。。相同则++计数。

 

    一开始想两种循环嵌套一起,但是分不清ab cd交换律相同的情况,就将两种情况分别讨论。

 

 

 

 

代码

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
#include <iostream>#include <algorithm>

using namespace std;

int main() {    int a,b,c,d,answer,count=0 , count1 = 0 ;    int org[4];    int ans[4];    for(a = 0; a<10 ; a++){        for(b = 0 ; b < 10; b++){            for(c = 0 ; c < 10 ; c++){                for (d = 0 ; d < 10 ; d++){                    if(a!= b && a!=c && a!=d && b!=c && b!=d && c!=d){                       org[0] = a; org[1] = b ; org[2] = c; org[3] = d;                       sort(org,org+4);                        answer = a *(b*100+c*10+d);                        if(answer >1000 && answer < 9999){                            ans[0] = answer%10; answer = answer/10;                            ans[1] = answer%10; answer = answer/10;                            ans[2] = answer%10; answer = answer/10;                            ans[3] = answer%10;                            sort(ans,ans+4);

                            for (int i = 0; i < 4; ++i) {                                if (ans[i] != org[i]){                                    break;                                }                                if(i == 3){                                    count++;                                }                            }                        }                    }                }            }        }    }    for(a = 0; a<10 ; a++){        for(b = 0 ; b < 10; b++){            for(c = 0 ; c < 10 ; c++){                for (d = 0 ; d < 10 ; d++){                    if(a!= b && a!=c && a!=d && b!=c && b!=d && c!=d){                        org[0] = a; org[1] = b ; org[2] = c; org[3] = d;                        sort(org,org+4);                        answer = (a*10+b)*(c*10+d);                            if(answer >1000 && answer < 9999){                                ans[0] = answer%10; answer = answer/10;                                ans[1] = answer%10; answer = answer/10;                                ans[2] = answer%10; answer = answer/10;                                ans[3] = answer%10;                                sort(ans,ans+4);                                for (int i = 0; i < 4; ++i) {                                    if (ans[i] != org[i]){                                        break;                                    }                                    if(i == 3) {                                        count1++;                                    }                                }                            }                    }                }            }        }    }

    cout<< count+(count1/2);}

3.冰壶比赛

 

题目描述:

    在冰壶比赛中,给出一个目标点P以及一个规定的正整数r。每一局由甲和乙两队轮流投冰壶各8次后,该局比赛结束。此时,哪一方的冰壶最终离目标点P更近,该方得分,另一方不得分。得分方每颗离目标点P距离小于或等于r、位置较另一队所有冰壶都更接近目标点P的冰壶都可以得1分

 

    比赛最多进行10局。双方之间的某局比赛结束后,落后一方可以弃权。此时,比赛不再进行下去

 

    已知每一局结束时,双方的每个冰壶离目标点P的距离以及正整数r,请写一个程序判断两队之间每一局比赛的得分,以及总得分

 

输入:

    第一行一个正整数r

 

    以下有若干行(不超过20行),每一行8个正整数(之间用一个空格间隔)

 

    第二行的第j个数表示第一局比赛结束时,甲方的第j个冰壶距离目标点P的距离

 

    第三行的第j个数表示第一局比赛结束时,乙方的第j个冰壶距离目标点P的距离

 

……

 

    第2k行的第j个数表示第k局比赛结束时,甲方的第j个冰壶距离目标点P的距离

    第2k+1行的第j个数表示第k局比赛结束时,乙方的第j个冰壶距离目标点P的距离

    如果有一方中途弃权,则最后一行(偶数行)只有一个整数-1,表示此时发生弃权情况

 

输出:

    输出若干行,每行两个整数,中间以一个冒号间隔,表示每一局比赛甲乙双方的比分(甲得分在前)。最后一行有2个整数,中间以一个冒号间隔,表示甲乙双方比赛的最终得分(甲得分在前)

    意思就是,先输入一个“标准”r,有10场比赛,每场比赛打8次,取最好成绩(最近的也就是最小的),再与对手最好成绩比较,比对手低的话一定不得分,比对手高的话还要比标准要小或等于才算得分,也就是说,每场比赛的得分,一定有一方不得分,有可能出现都不得分的情况,若弃权的话直接输出后return 0;即可。最后输出总的比分(计数即可)

主要还是枚举

 

样例输入

12

5 60 25 74 71 100 3 93

66 75 70 66 52 73 67 14

93 84 74 99 79 64 89 22

65 5 95 59 80 8 35 61

65 61 49 60 58 50 32 85

68 38 96 38 82 64 26 93

74 92 47 21 97 30 45 78

44 99 90 27 3 46 55 34

49 45 83 3 18 1 67 23

60 47 95 81 17 1 87 85

18 74 74 84 29 20 27 71

37 60 26 56 23 65 67 49

57 7 62 92 52 5 10 69

46 97 88 28 76 27 66 7

89 89 94 31 11 20 1 17

19 48 35 6 77 61 45 21

52 11 76 70 73 99 85 55

90 25 20 7 64 24 94 4

3 43 32 74 10 93 35 77

77 100 63 91 10 73 22 57

 

 

样例输出

 

2:0

0:2

0:0

0:1

0:0

0:0

1:0

1:0

0:2

1:0

5:5

 

 

样例解释:

可以看到标准为12,

第一局,甲最低3,乙最低14,3<14&&3<=12,甲得分,乙不得分

第二局,甲最低22,乙最低5,5<22&&5<=12,乙得分,甲不得分

第三局,甲最低32,乙最低26,都没有小于等于标准,都不得分

。。。。。。

 

代码

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
#include<iostream>#include<string>using namespace std;int main(){    int r,i,j;    cin>>r;    int a[9],b[9],f=0,f1=0,zf=0,zf1=0,min=10000,min1=100000;    for(i=1;i<=10;i++)    {        for(j=1;j<=8;j++)        {            cin>>a[j];            if(a[1]==-1)            {            cout<<zf<<':'<<zf1;            return 0;            }        }        for(j=1;j<=8;j++)        {            cin>>b[j];        }        for(j=1;j<=8;j++)        {            if(a[j]<min)            {                min=a[j];            }        }        for(j=1;j<=8;j++)        {             if(b[j]<min1)             {                min1=b[j];             }        }        if(min<min1)        {            for(j=1;j<=8;j++)            {                if(a[j]<=r&&a[j]<min1)                {                    f++;                }            }            cout<<f<<':'<<f1<<endl;            zf=zf+f;            f=0;        }        else if(min1<min)        {            for(j=1;j<=8;j++)            {                if(b[j]<=r&&b[j]<min)                {                    f1++;                }            }            cout<<f<<':'<<f1<<endl;            zf1=zf1+f1;            f1=0;        }        else        {            cout<<0<<':'<<0<<endl;        }        min=10000;        min1=10000;    }    cout<<zf<<':'<<zf1;    return 0;}

 

这里用到了求最小值的方法,还可以改成sort排序后的[0]

好了,今天的内容到现在就结束了,不知道大家有木有听懂呢?听不懂的别忘了在https://blog.csdn.net/weixin_45497223上给我留言,我会第一时间为大家解答的。明天一定要来哦,早上7:00,我们不见不散~~~

 

 

度娘:“你怎么不问我?[○・`Д´・ ○]”

0
王子健
王子健
初级天翼
初级天翼

枚举,说的简单一点就叫做一个一个可能性去找

比如:你要找1----10000里的质数,你就需要for循环start2到end10000一个一个去找质数

枚举没有什么框架,就是时间复杂度很高,一般在那种没有输入输出的题目中会用

 

当然枚举也有高深的用法,我不会,勿喷,谢谢

0
我要回答