蓝桥杯知识点模板

辗转相除法:

int GCD(int a,int b)
{
    if(a%b==0) return b;
    //如果a%b==0 代表可以被整除,那么b就是最大公约数

    else return GCD(b,a%b)

    // 如果不能被整除,那么就先取余数,代码会保证左侧是大的,右侧是小的数字,所以使用时不必进行大小检查,即使a<b也会再一次递归后变成b,a在进行计算。

    //这样就能按照辗转相除法求解。(小学五年级的课程吧)
}
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;

public class Main {

    static int check(int a, int b, int c)
    {
        int flag[]=new int[11];
        for(int i=0;i<10;i++) flag[i]=0;
        flag[0]=1;
        while(a!=0)
        {
            if(flag[a%10]==1) return 0;
            else flag[a%10]=1;

            if(flag[b%10]==1) return 0;
            else flag[b%10]=1  ;


            if(flag[c%10]==1) return 0;
            else flag[c%10]=1  ;

            a=a/10;
            b=b/10;
            c=c/10;

        }
        return 1;
    }

    public static void main(String[] args) {

        int ans=0;

        for(int a=123;a<=987;a++)
            for(int b=123;b<=987-a;b++)
            {
                int c=a+b;
                if(check(a,b,c)==1)
                {
                    ans++;
                    System.out.println(a+"+"+b+"="+c);
                }

            }
        System.out.println(ans);
    }
}

import java.util.Scanner;
import java.util.Stack;

public class Main {

    static Stack Mystack =new Stack();

    public static void main(String[] args)
    {
        int N;
        Scanner in=new Scanner(System.in);
        N=in.nextInt();
        for(int i=0;i<N;i++)
        {
            String op,name;
           op=in.next();
           name=in.next();
           // System.out.println(op+"  "+name);
            if(op.contains("in") )
                Mystack.push(name);

            else {
                while(!Mystack.peek().equals(name)){
                   // System.out.println(getTop());
                    Mystack.pop();
                }
                Mystack.pop();
            }
        }
        if(Mystack.empty()) System.out.println("Empty");
        else System.out.println(Mystack.peek());
    }

}

哈希表

import java.util.Scanner;
import java.util.Stack;

public class Main {

    static  final int h=999983;

    static String[] Value=new String [h];

    static String[] UpValue=new String [h];

    static int UpValueCount=0;

    static int   Hx(String s) {
        return (s.hashCode()%h+h)%h;
    }

    static boolean isAt(String s)
    {
        int n=Hx(s);
        if(Value[n]==null) return false;
        else if(Value[n].equals(s)) return true;
        else {
            for(int i=0;i<UpValueCount;i++)
                if(UpValue[i].equals(s)) return true;

            return false;
        }


    }

    static boolean in(String s)
    {
        int n=Hx(s);
        if(Value[n]==null) {
            Value[n]=s;
            return true;
        }
        else if(Value[n].equals(s)) return false;
        else {
            for(int i=0;i<UpValueCount;i++)
                if(UpValue[i].equals(s)) return false;

            UpValue[UpValueCount++]=s;
            return true;
        }
    }
    public static void main(String[] args)
    {

        int n;
        boolean flag=false;
        Scanner in=new Scanner(System.in);
        String ans="NO";
        n=in.nextInt();
        for(int i=0;i<n;i++)
        {
            String word;
            word=in.next();
            // System.out.println(Hx(word));
            if(flag) continue;

            if(isAt(word)){
                flag=true;
                ans=word;
            }
            else {
                in(word);

            }
        }
        System.out.println(ans);
    }

}

sort排序

import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;

public class Main {
    public static class MyComparator implements Comparator<Long> {
        @Override
        public int compare(Long a, Long b) {
            return a==b ?  0 : (a > b ? 1 : -1);
        }
    }
    public static void main(String[] args) {

        Long[] arr = new Long[500005];
        int n;
        Scanner in=new Scanner(System.in);
        n=in.nextInt();
        for(int i=0;i<n;i++)
        {
            arr[i]=in.nextLong();
        }
        Comparator<Long> cmp = new MyComparator();
        Arrays.sort(arr, 0,n,cmp); //也可以缺省cmp
        for (int i =0;i<n;i++){
            System.out.print(arr[i] + " ");
        }
        System.out.println("");
        for (int i = n-1; i >=0; i--)
        {
            System.out.print(arr[i]+" ");
        }
    }
}

Vector

import java.util.List;
import java.util.Scanner;
import java.util.Vector;

public class Main {

  static Vector city=new Vector<String>();


  static Vector <Vector<String>> dig= new Vector <Vector<String>>();

  static int Myfind(String s)
  {

      for(int i=0;i<city.size();i++)
      {
          if(city.get(i).equals(s)) {
              return i;
          }
      }

      return -1;
  }

  public static void main(String[] args) {


      int n;
      Scanner in=new Scanner(System.in);
      n=in.nextInt();
      for(int i=0;i<n;i++)
      {
          String d,c;
          d=in.next();
          c=in.next();
          int flag=Myfind(c);
          if(flag==-1){
              city.addElement(c);


              dig.addElement(new Vector<String>());
              dig.get(city.size()-1).addElement(d);

          }
          else   dig.get(flag).addElement(d);
      }
      for(int i=0;i<city.size();i++)
      {
          System.out.println(city.get(i)+" "+dig.get(i).size());

          for(int j = 0; j< dig.get(i).size(); j++)
              System.out.println(dig.get(i).get(j));
      }
  }


}
Queue队列
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {

    static Queue<String> V=new LinkedList<String>();

    static Queue<String> N=new LinkedList<String>();

    public static void main(String[] args) {

        int M;
        Scanner in=new Scanner(System.in);
        M=in.nextInt();
        while(M>0) //
        {
            M--;
            String op,name,type;
            op=in.next();
            // System.out.println("op"+op);
            if(op.contains("IN"))
            {
                name=in.next();
                type=in.next();
                if(type.contains("V")) {
                    V.offer(name);
                }
                else {
                    N.offer(name);
                }
                // System.out.println("name:"+name+"type:"+type);

                // System.out.println(Vqueue);
            }
            else
            {
                type=in.next();
                if(type.contains("V")){
                    V.poll();
                }
                else {
                    N.poll();
                }
                // System.out.println("type"+type);
            }
        }

        while(V.size()!=0)
        {
            System.out.println(V.poll());
        }
        while(N.size()!=0)
        {
            System.out.println(N.poll());
        }
    }

}

Map映射

import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;

public class Main {

  static Map mp=new TreeMap();

  public static void main(String[] args)
  {

      int n;
      boolean flag=false;
      Scanner in=new Scanner(System.in);
      String ans="NO";
      n=in.nextInt();
      for(int i=0;i<n;i++)
      {
          String word;
          word=in.next();
          // System.out.println(Hx(word));
          if(flag) continue;

          if(mp.containsKey(word)){
              flag=true;
              ans=word;
          }
          else {
              mp.put(word,true);

          }
      }
      System.out.println(ans);
  }

}

递归算法:

do(a,b,c...)
{
    //递归终止条件,即出口
    if(a==? ,b==? ,....) return 

    //递归条件
    if(条件1)
        do(参数1)

    else(条件2)
        do(参数2)

}

如本题,各子式间存在计算关系,可以化为:

do(a)
{
    if(a==0) return 0;
    if(a==1) return 1;

    return do(a-1)+do(a-2);
}

组合型枚举就是让你在 n 个中,随机选出 m 个,问你有多少种方案,而且每一种方案选择了哪 m 个,这就是组合型枚举

public class Main {

  static  int n;
  static int m;//选m个数
  static Vector<Integer> chosen = new Vector<Integer>();
  static <object> void calc(int x) {

      if (chosen.size() > m || chosen.size() + (n - x + 1) < m) //剪枝
          return;
      if (x == n + 1) { //选够了m个数输出
          String ansTem = "";

          for (int i = 0; i < chosen.size(); i++)
              System.out.print(chosen.get(i)+" ");

          System.out.println("");
          return;
      }
      calc(x + 1);
      chosen.addElement(x);
      calc(x + 1);
      chosen.remove((Object)x);
  }
  public static void main(String[] args) {
      Scanner in = new Scanner(System.in);
      n = in.nextInt();
      m = in.nextInt();
      calc(1);
  }
}

排列型枚举相对组合型枚举就简单了一点,就是 n 个的全排列,即从 n 个中选取 n 个但是关心内部的顺序。
相比较组合只关心有多少个集合,而排列是关心集合内的排列方式。即排列型枚举就是寻找 AnnA_{n}^nAnn​ 问题。

  static  int n;
  static int[] order =new int[20];
  static boolean[] chosen =new boolean[20];
  static <object> void calc(int x) {
      if (x == n + 1) { //选够了m个数输出
          String ansTem = "";
          for (int i = 1; i <=n ; i++)
              System.out.println(order[i]);
          return;
      }
      for (int i = 1; i <= n; i++) {
          if (chosen[i]) continue;
          order[x] = i;
          chosen[i] =true;
          calc(x + 1);
          chosen[i] = false;
          order[x] = 0;
      }
  }
  public static void main(String[] args) {
      Scanner in = new Scanner(System.in);
      n = in.nextInt();
      for (int i = 0; i < n; i++) {
         String s;
          s=in.next();
          name.addElement(s);
      }
      calc(1);
  }

差分算法解题的基本思路:

1、 b[1]=a[1];
2、 从第 2 项到 n 项,利用 b[i]=a[i]−a[i−1]b[i]=a[i]-a[i-1]b[i]=a[i]−a[i−1] 差分式;
3、 对于区间端点操作加减;
4、 差分还原(前缀和)。
注意是从1开始,从0开始还有讨论i=0 的情况,使用1的话 b[1]=a[1]-a[0]=a[1]-0;
首先假设有一个数组:

a[]={1 2 3 4 5 7 2}

差分后:

b[]={1 1 1 1 1 2 -5}

一般应用场景:

让你对区间 [l,r] 加减操作 N 次

如:

从第二个元素到第五个元素每个+3
从第二个元素到第四个元素每个-2
从第一个元素到第三个元素每个+1
....

这里我们先演示前三个:

对于每个 [l,r] 区间的加减操作都转化为对端点 l,r+1 的操作

从第二个元素到第五个元素每个+3:

转化为:[l]+3 并且 [r+1]-3

那么原序列变成了:

1 1 1 1 1 2 -5
1 4 1 1 1 -1 -5

然后我们按照 b[i]=b[i]+b[i-1] 复原:

1 5 6 7 8 7 2

去掉最后一项,跟原序列对比:

1 2 3 4 5 7 2
1 5 6 7 8 7 2

确实是都加上了 3。

我们继续操作:

从第二个元素到第四个元素每个-2

转化为:[l]-2 并且 [r+1]+2

那么序列变成了: 

1 4 1 1 1 -1 -5
1 2 1 1 3 -1 -5

然后我们按照b[i]=b[i]+b[i-1] 复原

1 3 4 5 8 7 2

与上次复原后对比:

1 5 6 7 8 7 2
1 3 4 5 8 7 2 

确实是按照操作执行了。

注意 Warning:

不用每次都复原,只用最后一次复原即可,这里我是演示给大家看。

我们最后直接做三次,最后还原:

从第二个元素到第五个元素每个+3
从第二个元素到第四个元素每个-2
从第一个元素到第三个元素每个+1

a[]={1 2 3 4 5 7 2}

原序列差分后:

b[]={1 1 1 1 1 2 -5}

2 号元素 + 3 
6 号元素 - 3
2 号元素 - 2
5 号元素 + 2
1 号元素 + 1 
4 号元素 - 1

差分序列变成:

2 2 1 0 3 -1 -5

复原后:

2 4 5 5 8 7 5

与原序列对比:

1 2 3 4 5 7 2
2 4 5 5 8 7 5

所以还是非常方便快捷的。

在这里插入图片描述

首先假设有一个数组:

1 2 3 4 5 7 2

前缀和后:

0 1 3 6 10 15 22 24

一般应用场景:

让你对区间 [l,r] 求和操作N次

如:

从第二个元素到第五个元素的和
从第二个元素到第四个元素的和
从第一个元素到第三个元素的和
....

这里我们先演示前三个:

对于每个 [l,r] 区间的求和操作转化为区间端点的加减操作

sum[l,r] =[r]-[l-1]

从第二个元素到第五个元素的和:

转化为:[5]-[1]

那么Sum[2,5]=[5]-[1]=142+3+4+5=14

确实是相等的,就是这么神奇。

我们继续操作:

从第二个元素到第四个元素的和

转化为:[4]-[1]

那么Sum[2,4]=[4]-[1]=92+3+4=9

我们继续操作:

从第一个元素到第三个元素的和

转化为:[3]-[0]

那么Sum[1,3]=[3]-[0]=61+2+3=6

符合题意,验证结束,咱么做个题目看一看

二分查找:

// 在单调递增序列a中查找>=x的数中最小的一个(即x或x的后继)
while (low < high) {

  int mid = (low + high) / 2;

  if (a[mid] >= x)
      high= mid; 

  else 
      low = mid + 1;
}

// 在单调递增序列a中查找<=x的数中最大的一个(即x或x的前驱)
while (low < high) {

  int mid = (low + high + 1) / 2;

  if (a[mid] <= x) 
      low = mid;

  else 
      high = mid - 1;

}

实数二分:

//令eps 为小于题目精度一个数即可。

//比如题目说保留4位小数,0.0001 这种的。那么eps 就可以设置为五位小数的任意一个数 0.00001- 0.00009 等等都可以。一般为了保证精度我们选取精度 /100 的那个小数,即设置  eps= 0.0001/100 =1e-6。

while (l + eps < r) {
  double mid = (l + r) / 2;

  if (pd(mid)) 
      r = mid; 
  else 
      l = mid;
}

// 实数域二分,规定循环次数法

//通过循环一定次数达到精度要求,这个一般log2N< 精度即可。N为循环次数,在不超过时间复杂度的情况下,可以选择给N乘一个系数使得精度更高。

for (int i = 0; i < 100; i++) {

  double mid = (l + r) / 2;
  if (pd(mid)) 
      r = mid; 
  else 
      l = mid;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值