目录
前言
马上要开始新星杯了,你有开始准备吗??所以今天来总结一些之间学过的算法吧(附加一道验证哥德巴赫猜想)🍗🍠🥠🥙。
一、快排(分区交换排序)
算法描述:
给出一个temp值(默认为数组第一个位置上的数),从数组开头 i 开始找大于temp的数,数组末端 j 开始找小于temp的数,找到之后两位置上的数进行交换,然后(i++,j--)继续找后面小于temp,前面大于temp的数进行交换,直到i=j;把基准点移到i位置,对基准点左右子序列分别进行递归,以此类推,最后得到一个排序好的数组。🐏🐏🐑
图片模拟:
代码实现:
#include<stdio.h>
int a[100],n;
void fun(int left,int right)
{
int i,j,t,temp;
if(left>right)
return;
temp=a[left];
i=left;j=right;
while(i!=j)
{
while(a[j]>=temp&&i<j)
j--;
while(a[i]<=temp&&i<j)
i++;
if(i<j)
{
t=a[i];
a[i]=a[j];
a[j]=t;
}
}
a[left]=a[i];
a[i]=temp;
fun(left,i-1);
fun(i+1,right);
}
int main()
{
int t;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
fun(1,n);
for(int i=1;i<=n;i++)
printf("%d",a[i]);
getchar();getchar();
return 0;
}
二、前缀和
算法思想:
假定数列 a[n]:a[0],a[1],a[2],a[3]...
其前缀和就是s[n]:s[0]=a[0]; s[1] =a[0]+a[1]......s[n]=a[0]+a[1]+a[2]+....a[n];
所以可以应用例如:s[5]-s[3]=a[5]+a[4];
很简单的,我相信你已经明白了吧!!👻👻👻
例题:
输入n,k;代表n个数字存入a[n],输出a[n]中长度为k的所有连续部分和
代码实现:
#include<stdio.h>
int a[1000000]={0},s[100000]={0};
int main()
{
long long n,k,i,t=0,sum=0;
scanf("%lld %lld",&n,&k);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=n;i++)
{
s[i]=s[i-1]+a[i];
}
for(i=1;i<=n-k+1;i++)
{
t=s[i+k-1]-s[i-1];
sum+=t;
}
printf("%lld\n",sum);
return 0;
}
三 、差分
算法思想:
差分,是一种和前缀和相对的策略。
这种策略是,令b [i]=a[i]−a[ i−1],即相邻两数的差。
易得对这个序列做一遍前缀和就得到了原来的序列。
例题:
四、验证哥德巴赫猜想
思路:
设置两个函数(sushu函数判断是否为素数,fun函数将需要验证的数拆解成两个数,进入fun函数进行验证)。假如分解的两个数都是素数,就输出。
代码实现:
#include<stdio.h>
#include<math.h>
int sushu(int n)//判断是否为素数
{
int flag=0;
for(int i=2;i<=sqrt(n);i++)
{
if(n%i==0)
{
flag=1;
break;
}
}
return flag;
}
int fun(int n)
{
int a,b,flag1,flag2;
for(a=2;a<n;a++)
{
b=n-a;//将n分解为a,b
flag1=sushu(a);
flag2=sushu(b);//判断a,b是否都是素数
if(flag1==0&&flag2==0)
return a;//如果是则返回a
}
return 0;
}
int main()
{
int p1,p2;
for(int i=4;i<=2000;i=i+2)//对大于2小于2000的偶数进行判断
{
p1=fun(i);//调用fun函数
if(p1!=0)
{
p2=i-p1;//如果返回素数,输出
printf("%d=%d+%d",i,p1,p2);
}
}
return 0;
}