oj之路(第一天)(续:由题目看思想)

Today, it's a good day! Doesn't it?

废话不多说了,直接进题目

=======================================================================================================

Description:
数学对于计算机学是很重要的,大一的高数就曾经(或即将)令一批又一批人饮恨。这里就是一个数学问题,当然,它不需要用到高深的高数知识。
给出n(1<=n<=100000),问1到n之间有几个素数。 
输入格式
第1行,1个整数T(T<=100000),表示共有T组测试数据
第2---第T+1行,每行1个整数,表示测试数据n 
输出格式
对于每个测试数据,输出1行,每行1个数,表示1到n之间的素数个数
输入样例
5
1
2
100
1000
5000
输出样例
0
1
25
168
669

=======================================================================================================

思考过程:
看题目发现这次要求的数据次数还算挺大的,而且每次都是求一个相同的问题,那么这里就会用到”记忆搜索“的思想(我的上一篇博客提及的)。
我们应该首先把所有的素数和素数范围内的个数求出来,然后保存到数组里面去。之后要求的数据一输入就能得到相应的答案了。
求素数带来的问题:
Q:100000以内的素数这么大,我们要怎么快速确定那个数是素数呢?
A:这里我要介绍一种算法(挺牛的),以下是算法描述(就一句话):
如果一个数能被【2,根号(该数)】这个范围内的素数整除,那么这个数就不是素数,否则就是素数。---------------------------------------------------------(重点思想)
所以这种算法需要记录素数,以便为后来的判断素数提供快捷之道--又是”记忆搜索“的思想(发现这种思想真是挺万能的)。

=======================================================================================================

源代码:

#include <stdio.h>
#include <math.h>
int primeCt[100001];
int prime[1000];		//这里正确答案是prime[10001],为什么?
int count = 1;
int Prime(int n)
{
	int tmp = (int)sqrt((double)n);
	for (int i = 0; prime[i] <= tmp; ++i) {		//这里的tmp的值最多也就316左右,那么prime[i]的值应该不用存储那么多对吧?
		if (n % prime[i] == 0)
			return 0;
	}
	return 1;
}
int main()
{
	prime[0] = 2;
	primeCt[2] = 1;
	for (int i = 3; i <= 100000; ++i) {
		if (Prime(i))
			prime[count++] = i;		//因为这里的count可以到达9000+,会越界。特别注意数组的问题,要不然会被坑。我就是本坑了~
		primeCt[i] = count;
	}

	int T;
	scanf("%d", &T);
	while (T--) {
		int m;
		scanf("%d", &m);
		printf("%d\n", primeCt[m]);
	}
	return 0;
}

=======================================================================================================

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值