枚举和二分

         一切都从头开始,今天先复习枚举和二分。枚举就不多说了,说一下二分,二分其实是分治的一种,是当n=2是的一种情况,也叫二分查找(折半查找),二分查找速度快,比你从头一个一个的查可快多了,二分查找是每次把集合一分为二,看你要找的是在前一半还是后一半,如果在前一半再把前一半一分为二以此类推知道找到你想要的,在后一半同理。二分查找的条件之一是元素表必须是有序表。下面两个模板

 1 int l,r,res;//l为左边界,r为右边界,具体值要看目,res为记录mid值的
 2 while(l<=r){//循环条件很重要,当l>r时循环结束,res记录的是l=r时的值
 3     int mid=(l+r)/2;
 4     if(ok(mid)){//ok函数要看题目具体设计
 5         l=mid+1;//选哪个要看题
 6         //r=mid-1;
 7         res=mid;
 8     }
 9     else 
10         r=mid-1;
11         //l=mid+1;
12 }
 1 //第一个是整形二分,下面是浮点型二分
 2 #define eps 1e-8 //定义宏eps,eps是精度
 3 double l,r;
 4 while(l+eps<r){
 5     double mid=(l+r)/2.0;//注意除的是2.0
 6     if(ok(mid)){
 7         l=mid;//注意没有减一或加一
 8         //r=mid;
 9     } 
10     else
11         r=mid;
12         //l=mid;
13 }
前两天刚做的一个题。题意是给你个整形变量n查找从1~n内的special number个数(0<n<=10000000),special number就是这个数不能有重复的数字出现也不呢不过有前导0,比如023,1124都不是,1234就是。这个题不难但是有时间限制所以关键是看判断是special number 的优化。
 1 #include<cstdio>
 2 #include<cstring>
 3 #define maxn 10000000
 4 using namespace std;
 5 int a[5000000];///存的是special number
 6 ///判断是否是特别数
 7 bool ok(int x){
 8     bool vis[10],flag=true;///假设这个数最大有10位,vis的作用就是记录他的每位数是否出现过
 9     memset(vis,false,sizeof(vis));//先初始化为没出现过
10     while(x){
11         int tmp=x%10;///取每位数
12         x=x/10;
13         if(vis[tmp]){
14             flag=false;///如果这位数曾经出现过则这个数就不是特别数
15             break;
16         }
17         vis[tmp]=true;///否则记录出现过
18     }
19     return flag;
20 }
21 int main(){
22     memset(a,0,sizeof(a));
23     int cnt=0;
24     for(int i=1; i<=maxn; i++){///先把所有的特别数按顺序存储在数组里,这就是枚举
25             if(ok(i))
26                 a[cnt++]=i;///cnt+1是所有特别数的个数
27     }
28     int n;
29     while(~scanf("%d",&n)){
30         int l=0,r=cnt-1,res;
31         if(n<=1){
32             printf("%d\n",0);
33             continue;
34         }
35         while(l<=r){///分的是下标,因为小于n的特别数个数就是小于n的树中最大特别数的下标+1。(好好想想,因为特别数已经按顺序存储)
36             int mid=(l+r)/2;
37             if(a[mid]<n){
38                 l=mid+1;
39                 res=mid;
40             }
41             else
42                 r=mid-1;
43         }
44         printf("%d\n",res+1);
45     }
46 }

 







posted @ 2016-08-05 14:39  Yang_J  阅读(403)  评论(0编辑  收藏  举报