2020-10-08 — 2020-10-11 学习总结


前言

洛谷入门题目知识点整理和一些基础知识点

一、基础知识巩固

1 结构体

定义一个结构体:

strunct man 
{
char name[10];
int age;
}

eg:

#include<stdio.h>
struct man
{
	char name[10];
	int age;
};
int main()
{
	struct man wjc;
	wjc.name[0]='z';
	wjc.age=1000; 
	printf("%s %d",wjc.name,wjc.age);
}

2 递归

//10的阶乘 
#include<stdio.h>
int mul(int x)
{
	return x==1? 1 : x*mul(x-1); //套娃行为 
}
int main()
{
	printf("%d",mul(10));
}
 

3 最多保留两位小数

double类型,如果是整数则不用输出小数部分,如果是一位小数则输出一位,否则输入两位小数。
如何实现:

if (floor(ans)==ans){
printf("%d",ans) ;
}//说明ans没有小数位,直接用整数方法输出

else if (floor(ans*10)==ans*10){
	printf("%.1f",ans);
}//说明ans小数点向右移动一位后就没有小数了,说明是一位小数

printf("%.2f",ans);//否则小数位大于等于2,直接%.2f输出

4.memset函数

多用于清空数组,对一段内存空间全部设置为某个字符(一般为0,1或-1),原型是

memset(butter,0,sizeof(buffer))
eg: char a[10];memset(a,1,10);

头文件是…是啥来着,我查查
#include<string.h>
误区:memset的内部实现是以字节为单位进行赋值的,如果是int 类型则大于一个字节,会报错。

二、对角线求结点

题目:对于一个 n 个顶点的凸多边形,它的任何三条对角线都不会交于一点。请求出图形中对角线交点的个数。对于 50%的数据,保证3≤n≤100.对于100%的数据,保证3≤n≤10e5.

1.分析

从对角线和结点的关系入手,可分析出结点一定为两条对角线相交所得,不存在三条或多条对角线相交得一个结点的情况。
再从多边形顶点和对角线的关系入手,两条对角线可以确定四个顶点,反推每四个顶点组合就能确定两条对角线和一个结点。所以只需求出该多边形有几种四个顶点组合就能确定出有几个结点。

在这里插入图片描述

2. 源代码

#include<stdio.h>
int main()
{
	unsigned long long n,a;
	
	scanf("%lld",&n);
if(n<=3)
{
printf("0");
}
else{
	a=n*(n-1)/2*(n-2)/3*(n-3)/4;//防止爆掉
	printf("%lld",a);
}
return 0;
}

三、质数筛

1.暴力法的优化

暴力法:直接从2到n遍历看是否能整除,但可以分析出只需要取到sqrt(n)即可,因为两个因数必定在sqrt(n)的两侧
承接题目:输入 n(n≤100) 个不大于 100000 的整数。要求全部储存在数组中,去除掉不是质数的数字,依次输出剩余的质数。

bool isPrime_1( int num )
{
	int i;
	if(num<=1)return false;
	for(i=2;i<=sqrt(num);i++)
	{
		if(num%i==0) return false;
	}
	return true;
	if(num==2||num==3) return true;
}

源代码:

#include<stdio.h>
#include<math.h>
#include<stdbool.h>
bool Isprime (int num)
{
	int i;
	if(num<=1)return false;
	for(i=2;i<=sqrt(num);i++)
	{
		if(num%i==0) return false;
	}
	return true;
	if(num==2||num==3) return true;
}
int main()
{
	int n;
	int j;
	int b[100];

	scanf("%d",&n);
	for(j=0;j<n;j++)
	{
		scanf("%d",&b[j]);
	}
	

	for(j=0;j<n;j++)
	{
		if(Isprime(b[j]))
		{
			printf("%d ",b[j]);
		}
	}
	return 0 ;
}

2.步长为6的优化

令x>=1的话,可以将大于5的自然数表示为
······ 6x-1,6x,6x+1,6x+2,6x+3,6x+4,6x+5,6(x+1),6(x+1)+1 ······

可以看到有一个循环6x-1,6x,6x+1,6x+2,6x+3,6x+4
不难知道不在6x左右两侧的数一定不是质数,但在两侧的数也不一定都是质数,所以删掉不在两侧的数,只对两侧的数判断是否为质数就好。

bool Isprime(int n)
{
	if (n==1) return false;
	if (n==2||n==3) return ture;
	if(n%6!=1&&n%6!=5) return false;//判断不在两侧
	for(i=5;i*i<=n;i+=6){
	if(n%i==0||n%(i+2)==0) return false;
	return true; }
}

emmm…

3.埃氏筛

看了一些解释我理解的是所有合数都可以由素数乘素数得来,所以只要将已知素数作为因数做乘法,删除所得数(合数)即可。
源代码:

//埃氏筛法 
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
#include <string.h>
bool num[101];
int i,j,n;
int main()
{
	memset (num,1,sizeof(num));
	scanf("%d",&n);
for (i=2;i<=sqrt(n);i++)
{
	if(num[i])
	{
		for(j=i*i;j<=n;j+=i)//筛去合数 
		num[j]=0;
	}
	}
for(i=2;i<=n;i++)	
{
	if(num[i])
	printf("%d ",i);
}
return 0;
}

3.(线性筛)欧拉筛
还没有弄明白,之后补上orz

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值