14周学习笔记

2023/12/11

14周学习笔记

快速幂指算法

在这里插入图片描述
再写题之前,学到了取模运算法则
设a,b,c都为非0正数。
1、(a%c+b%c)%c=(a+b)%c
2、(ab)%c=(a%cb%c)%c
快速幂指法主要运用了第二种方法。
设保留最后c位小数
算法思路:例如3^5,若要对其结果取余,我们可以拆为(3 3%c3 3%c3%c)%c,我们可以
先把3%c存起来,然后变为3^2求解,指数为奇数时存下3%c,然后对让指数除二,之后让底数
变为原来两倍,若之后指数满足大于0,则继续进行循环,直到指数除2得0时结束循环。返回she的值。


```c
在这里插入代码片#include<stdio.h>
long long  ZPY(long long wo, long long ai)
{
    long long she=1;
    while(ai>0)
    {
        if(ai%2==1)
        {
            she=she*wo%10000;
        }
        ai=ai/2;
        wo=(wo*wo)%10000;
    }
    return she;
}
int main()
{
     int T,i,a,b,sum;
    scanf("%d",&T);
    for(i=0;i<T;i++)
    {
        scanf("%d %d",&a,&b);
         sum=ZPY(a,b);
        printf("%04lld\n",sum);
    }
    return 0;
}

半分查找法

#include<stdio.h>
int main()
{
    int n,i,j,k,number,a[1000],count=0;
    scanf("%d %d",&n,&number);
    getchar();
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);//输入n组递增的数据
    }
    int low,high,mid;
    low=0,high=n-1;
    while(low<=high)
    {
        mid=(low+high)/2;
        if(a[mid]<number)
        {
            low=mid+1;
        }
        if(a[mid]>number)
        {
            high=mid-1;
        }
        if(a[mid]==number)
        {
            count++;
            break;
        }
    }
    if(count==0)
    {
        printf("找不到\n");
    }
    else printf("找到了\n");
     return 0;
}

半分查找大大减少了时间复杂度,就是当查找的数据量很大的时候,用循环查找太过麻烦,虽然电脑计算能力很快,逐个循环查找,利用半分查找减少了电脑计算时间,更加方便。
首先定义三个整型数据,low、high、mid,分别为被查找数中的第一位和最后一位,mid就位low和high相加除2了,观察查找值与mid相互比较,若查找值大于mid则让下一次循环时low=mid+1,在比较。若查找值小于mid,则让high=mid-1,以此推理。最后当mid等于查找值时让count加1,结束循环,若一直未找到,直到low大于high时结束循环,输出找不到。

sscanf函数

在这里插入图片描述

在这里插入代码片#include<stdio.h>//四则运算
int main()
{
   int n,i,j,a,b;
   float sum;
   char arr[110][30];
   scanf("%d",&n);
   for(i=0;i<n;i++)
   {
       scanf("%s",arr[i]);
   }
   for(i=0;i<n;i++)
   {
       if(arr[i][0]=='a')
       {
           sscanf(arr[i],"add(%d,%d)",&a,&b);
           printf("%d\n",a+b);
       }
       if(arr[i][0]=='m')
       {
           sscanf(arr[i],"mul(%d,%d)",&a,&b);
           printf("%d\n",a*b);
       }
       if(arr[i][0]=='s')
       {
           sscanf(arr[i],"sub(%d,%d)",&a,&b);
           printf("%d\n",a-b);
       }
       if(arr[i][0]=='d')
       {
           sscanf(arr[i],"div(%d,%d)",&a,&b);
           if(b==0)
           {
               printf("error\n");
           }
           else
           {
               if(a%b==0)
               {
                   printf("%d\n",a/b);
               }
               else
               {
                   sum=(float)a/b;
                   printf("%.2f\n",sum);
               }
           }
       }
   }
   return 0;

}

sscanf函数能读出字符串中所想要的数据,并提出来计算。其用法多样,根据所想要的数据类型可以读出。

欧拉筛法

在这里插入图片描述

在这里插入代码片#include<stdio.h>
#include<stdbool.h>
int main()
{
    bool decide[1100000];
    int a[10000],i,j,count,m;
    while(scanf("%d",&m)!=EOF)
    {
        count=0;
        for(i=2; i<=m; i++)
        {
            decide[i]=true;
        }
        for(i=2; i<=m; i++)
        {
            if(decide[i])
            {
                a[count]=i;
                count++;
            }
            for(j=0; j<count&&a[j]*i<=m+1; j++)
            {
                decide[a[j]*i]=false;
                if(i %a [j]==0)
                    break;
            }
        }
        for(i=0; i<count; i++)
        {
            printf("%d\n",a[i]);
        }
    }
    return 0;
}

欧拉筛法时间复杂度为o(n),要求数据量大时可大大节省时间,使用到了bool类型标记质数和合数,核心代码是当i%a[j]==0时结束循环,保证其被最小数相除,不用再循环标记运算了。

前缀和算法

当数据量非常大的时候,我们求多个区间的和时,运用传统思路循环遍历求和时过于繁琐,而且费时间,虽然是计算机。因此我们定义一个数组存放大数据时,再定义一个数组用来存放从数据1到第n个数据和。即用数学公式表达为:b(n)=b(n-1)+a(n),前提b(0)=a(0),b(n)代表了a数组从第一个到n个之和,因此我们计算区间l到m和时,只要用b(m)-b(l)思路,求出区间和,避免了繁琐计算。

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值