做题基础~~~tips

做题小技巧(持续更新)

  • 拆分数字x
  • 关于长度
  • 查找一个数n的全部因子
  • 找出小于等于x的素数
    • 埃氏筛法
    • 欧拉筛法

拆分数字x

关于长度

查找一个数n的全部因子

找出小于等于x的素数

埃氏筛法

欧拉筛法

1.拆分数字x(可以很大噢)

int x,a[10005],c=0;//a[]数组存放拆分出来的每个数字,c用于标记数字在数组里存放的位置
	scanf("%d",&x);
	while(x){
     
		a[c++]=x%10;
		x/=10;
	}
	for(int i=c-1;i>=0;i--)//正序输出
		printf("%d ",a[i]);

2.关于长度:
字符串数组长度:strlen()
整型数组长度:sizeof(arr)/sizeof( int )
注意:这里得到的是数组的总长度(即我们定义它的时候的大小),而不是数组中存放有意义的数据的个数
(实在不行就用定义一个量来追踪它就好啦)

3.查找一个数n的全部因子:(或者是因子的个数)

#include 
using namespace std;
int main(){
     
	int n; 
	int a[10005];//装n的所有因子
	int z=0;//辅助数组装因子的位置
	scanf("%d",&n);
	for(int i=1;i*i<=n;i++){
     
		if(n%i==0){
     
			a[z++]=i;
			if(i!=(n/i)){
     //因为是在n/2前找所以可以用这个方法来查找n/2后的符合条件的数
				a[z++]=n/i;
			}
		}
	}
	return 0;
}

4.找出一定范围x的素数
方法一:埃氏筛法

#include 
using namespace std;
int visit[100005]={
     0};//先假设全部都为素数
//0为素数   1为非素数 
int main() 
{
     
	int x;
	scanf("%d",&x);
	for(int i=2;i<=x;i++){
     
		if(!visit[i])
			for(int j=i*i;j<=x;j+=i) 
				visit[j]=1;
	}
	for(int i=2;i<=x;i++)
		if(!visit[i])
			printf("%d ",i);	 
    return 0;
}

这里的ii做了一个小优化,因为i(2 ~ i-1)在2~i-1时已经被筛去辽
但是,埃氏筛法有一个弊端,就是重复判断同一个数,重复筛去同一个数,这也会浪费时间,当数据很大时也可能会超时。
为了解决这个弊端,我们引进一种新的方法:欧拉筛法。
方法二:欧拉筛法(它可以让每个合数只被它最小的质因子筛选一次!!!超厉害!!!他也太聪明了叭!!!!

#include 
using namespace std;
//设0为素数  1为非素数 
int visit[100005]={
     0};//访问每个位置,判断 
int prime[100005]={
     0};//储存  
int Prime(int x){
     
	int n=0;
	for(int i=2;i<=x;i++){
     
		if(!visit[i])
			prime[n++]=i;
		for(int j=0;j<n&&i*prime[j]<=x;j++){
     
			visit[i*prime[j]]=1;
			if(i%prime[j]==0) break;//这个得细细琢磨,是这个方法的精髓!!! 
		}
	}
	return n; //记录找到了多少个素数 
}
int main() 
{
     
	int x;
	scanf("%d",&x);
	int sum=Prime(x);
	for(int i=0;i<sum;i++){
     
		printf("%d ",prime[i]);
	}
	cout<<endl<<sum;
    return 0;
}

这个方法中i*prime[j] 以及i%prime[j]==0这两步 可以通过打印出每一步的过程来帮助我们理解。比如:
做题基础~~~tips_第1张图片
我们可以看到,i在消去合数中的作用是:当做倍数来帮助代码找到合数并消去。

你可能感兴趣的:(自己的算法,算法)