zoukankan      html  css  js  c++  java
  • 枚举和二分

             一切都从头开始,今天先复习枚举和二分。枚举就不多说了,说一下二分,二分其实是分治的一种,是当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
    ",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
    ",res+1);
    45     }
    46 }






  • 相关阅读:
    idea Ctrl+Alt+向下箭头 复制不起作用问题解决
    @Data 注解使用
    idea class类增加注释
    mysql 固定用户赋值数据库权限
    springboot logback 详细配置
    gitblit 增加ssh key
    uniapp内嵌H5页面和uniapp页面相互传值
    博客搬家
    反编译,java字节流 ,wirshark抓包,php转换中文
    charles 双向抓包
  • 原文地址:https://www.cnblogs.com/yjb333/p/5741290.html
Copyright © 2011-2022 走看看