第九周学习总结

一、桶排序

a、算法思路

假设我们要对{3,5,4,2,1}这5个数来进行升序排序,我们可以先找出对应其编号的5个桶出来,分别按数字顺序放入对应的桶中,例如数字3放在对应的3号桶......(在程序中,可以通过数组来实现)

例题:校门外的树

某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即0,1,2,……,L,都种有一棵树。

由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。

输入

输入文件tree.in的第一行有两个整数L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。

输出

输出文件tree.out包括一行,这一行只包含一个整数,表示马路上剩余的树的数目。

话不多说,先放代码:

#include
#include
int main()
{
     int l,m,a[10001]={0},i,x,y,s=0;
            //数组a为排序时用到的桶,并赋值0,代表每个数据都放在相应的桶里了
     scanf("%d%d",&l,&m);
     while(m--)
     {
         scanf("%d%d",&x,&y);
         while(x<=y)
         {
             a[x]=1;        //把每个非排序的数据赋值为1,
             x++;
         }
     }
     for(i=0;i<=l;i++)
     {
         if(a[i]==0)        //最后只有排好的数据了,全部打印
            s++;
     }
     printf("%d\n",s);
}

二、埃氏筛法

1、算法思路

我们可以先创建一个n长度的数组,然后来存储是否是素数(数组中的值可以用1来表示素数,0表示非素数),然后下表从2开始,将2的倍数的下标数组中的值赋为0,为非素数,然后又从3开始并且判断下标为3 的数组的值是否为1,为1则将3倍数开始,数组中值赋为0(表示非素数)。

例题

找[2,n]之间的所有素数(2<=n<=1000000)

#include
#include
long long a[1000001];
int main()
{
     long long n,i,j,k;
     while(~scanf("%lld",&n))
     {
         for(k=2;k<=n;k++)    //将数组的值先全部赋为1(初始化)
         a[k]=1;
            for(i=2;i<=n;i++)    //下标从2开始,求素数
            {
                if(a[i]!=0)
                {
                    printf("%lld\n",i);        //输出素数
                    for(j=i+i;j<=n;j+=i)    //把i的倍数下标的数组的值全部赋为0,表示非素数
                            a[j]=0;
                }
            }
     }
}

三、前缀和

1、算法简介

前缀和是指在某一个序列的前n项和,可以将它理解为高中数学中的数列前n项的和

2、算法思想

通过创建一个数组,边输入边将输入的前n项的和赋值到数组下标的第i项去

3、话不多说,上例题

 这一天,jz学长又发现了自己的童年玩具---异能机器,但是此时的异能机器出现了一点小bug(问题),但是jz学长需要异能机器帮他运算一串数列,每次问异能机器处于[l,r]这个区间的相反数和是多少。(注意序列长度为5*10^5,询问次数为5*10^5),你能帮帮他吗?

输入

第一行输入n,q
n表示序列长度,q代表询问次数
第二行n个数(-10^5 <= ai <= 10^5)
a1....an
第三行q组询问
[l1,r1]
........
[ln,rn]

输出

每一组询问对应一个输出,表示l-r这个区间的相反数和。

样例输入 复制

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

样例输出 复制

-6
-9
-3
#include
int main()
{
    long long n,q;
    scanf("%ld%ld",&n,&q);
    long long  a,t[n+10];    
    int i;
    t[0]=0;
    for(i=1;i<=n;i++)
    {
        scanf("%ld",&a);        //输入数列
        t[i]=a+t[i-1];           //记下数组前n项的和
    }
    int l,r;
    while(q--)
    {
        scanf("%ld%ld",&l,&r);
        printf("%ld\n",t[l-1]-t[r]);
    }
}

四、二分查找

1、算法实现的条件

        a、用于查找的内容逻辑上来说是需要有序的

        b、查找的数量只能是一个,而不是多个

2、算法思路

假如说我们要在一个升序的数组中找一个数,我们可以先把数组分成两半,先看那个数会在哪个区域,然后再将那个区域又分成两半,依次继续下去,直到找到那个数

3、例题

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。


示例 1:

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
示例 2:

输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
链接:https://leetcode.cn/problems/binary-search

int search(int* nums, int numsSize, int target){
    int low=0,high=numsSize-1;    
    while(low<=high)
    {
        int half=low+(high-low)/2;    //定义一个中间节点
        if(target>nums[half])    //判断是否在上半部分
            low=half+1;
        else if(target

你可能感兴趣的:(学习,算法,数据结构)